aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.idea/inspectionProfiles/c_geo_standards.xml243
-rw-r--r--main/build.gradle9
-rw-r--r--main/libs/jackson-annotations-2.4.1.jarbin0 -> 38604 bytes
-rw-r--r--main/libs/jackson-annotations-2.4.1.jar.properties2
-rw-r--r--main/libs/jackson-core-2.4.1.1.jarbin0 -> 225356 bytes
-rw-r--r--main/libs/jackson-core-2.4.1.1.jar.properties2
-rw-r--r--main/libs/jackson-databind-2.4.1.3.jarbin0 -> 1074135 bytes
-rw-r--r--main/libs/jackson-databind-2.4.1.3.jar.properties2
-rw-r--r--main/libs/src/jackson-annotations-2.4.1-javadoc.jarbin0 -> 268648 bytes
-rw-r--r--main/libs/src/jackson-annotations-2.4.1-sources.jarbin0 -> 42638 bytes
-rw-r--r--main/libs/src/jackson-core-2.4.1.1-javadoc.jarbin0 -> 800071 bytes
-rw-r--r--main/libs/src/jackson-core-2.4.1.1-sources.jarbin0 -> 235209 bytes
-rw-r--r--main/libs/src/jackson-databind-2.4.1.3-javadoc.jarbin0 -> 4055002 bytes
-rw-r--r--main/libs/src/jackson-databind-2.4.1.3-sources.jarbin0 -> 770115 bytes
-rw-r--r--main/proguard-project.txt3
-rwxr-xr-xmain/project/libraries/update-libs.sh10
-rw-r--r--main/res/values/changelog_master.xml3
-rw-r--r--main/res/values/preference_keys.xml1
-rw-r--r--main/src/cgeo/geocaching/AbstractDialogFragment.java2
-rw-r--r--main/src/cgeo/geocaching/CacheDetailActivity.java11
-rw-r--r--main/src/cgeo/geocaching/CacheListActivity.java8
-rw-r--r--main/src/cgeo/geocaching/CachePopupFragment.java12
-rw-r--r--main/src/cgeo/geocaching/CgeoApplication.java18
-rw-r--r--main/src/cgeo/geocaching/CompassActivity.java23
-rw-r--r--main/src/cgeo/geocaching/DataStore.java32
-rw-r--r--main/src/cgeo/geocaching/Geocache.java32
-rw-r--r--main/src/cgeo/geocaching/GpxFileListActivity.java126
-rw-r--r--main/src/cgeo/geocaching/MainActivity.java44
-rw-r--r--main/src/cgeo/geocaching/SelectMapfileActivity.java6
-rw-r--r--main/src/cgeo/geocaching/activity/AbstractActivity.java4
-rw-r--r--main/src/cgeo/geocaching/apps/cache/navi/PebbleApp.java50
-rw-r--r--main/src/cgeo/geocaching/concurrent/BlockingThreadPool.java57
-rw-r--r--main/src/cgeo/geocaching/concurrent/PriorityThreadFactory.java25
-rw-r--r--main/src/cgeo/geocaching/connector/AbstractConnector.java6
-rw-r--r--main/src/cgeo/geocaching/connector/capability/ILogin.java5
-rw-r--r--main/src/cgeo/geocaching/connector/ec/ECApi.java51
-rw-r--r--main/src/cgeo/geocaching/connector/ec/ECLogin.java20
-rw-r--r--main/src/cgeo/geocaching/connector/gc/GCConnector.java5
-rw-r--r--main/src/cgeo/geocaching/connector/gc/GCConstants.java1
-rw-r--r--main/src/cgeo/geocaching/connector/gc/GCLogin.java7
-rw-r--r--main/src/cgeo/geocaching/connector/gc/GCMap.java103
-rw-r--r--main/src/cgeo/geocaching/connector/gc/GCParser.java247
-rw-r--r--main/src/cgeo/geocaching/connector/gc/Tile.java52
-rw-r--r--main/src/cgeo/geocaching/connector/oc/OCApiConnector.java13
-rw-r--r--main/src/cgeo/geocaching/connector/oc/OkapiClient.java290
-rw-r--r--main/src/cgeo/geocaching/connector/oc/OkapiError.java14
-rw-r--r--main/src/cgeo/geocaching/connector/ox/OpenCachingApi.java6
-rw-r--r--main/src/cgeo/geocaching/files/AbstractFileListActivity.java28
-rw-r--r--main/src/cgeo/geocaching/files/FileTypeDetector.java3
-rw-r--r--main/src/cgeo/geocaching/files/GPXImporter.java5
-rw-r--r--main/src/cgeo/geocaching/files/GPXParser.java2
-rw-r--r--main/src/cgeo/geocaching/files/IFileSelectionView.java2
-rw-r--r--main/src/cgeo/geocaching/files/InvalidXMLCharacterFilterReader.java190
-rw-r--r--main/src/cgeo/geocaching/files/LocParser.java2
-rw-r--r--main/src/cgeo/geocaching/files/SimpleDirChooser.java2
-rw-r--r--main/src/cgeo/geocaching/filter/PopularityFilter.java3
-rw-r--r--main/src/cgeo/geocaching/filter/PopularityRatioFilter.java3
-rw-r--r--main/src/cgeo/geocaching/gcvote/GCVote.java5
-rw-r--r--main/src/cgeo/geocaching/geopoint/Viewport.java16
-rw-r--r--main/src/cgeo/geocaching/list/AbstractList.java2
-rw-r--r--main/src/cgeo/geocaching/list/StoredList.java36
-rw-r--r--main/src/cgeo/geocaching/maps/CGeoMap.java66
-rw-r--r--main/src/cgeo/geocaching/network/HtmlImage.java18
-rw-r--r--main/src/cgeo/geocaching/network/Network.java23
-rw-r--r--main/src/cgeo/geocaching/network/OAuth.java10
-rw-r--r--main/src/cgeo/geocaching/network/OAuthAuthorizationActivity.java58
-rw-r--r--main/src/cgeo/geocaching/network/OAuthTokens.java38
-rw-r--r--main/src/cgeo/geocaching/network/SmileyImage.java34
-rw-r--r--main/src/cgeo/geocaching/network/StatusUpdater.java23
-rw-r--r--main/src/cgeo/geocaching/sensors/GeoData.java30
-rw-r--r--main/src/cgeo/geocaching/sensors/GeoDataProvider.java144
-rw-r--r--main/src/cgeo/geocaching/sensors/GpsStatusProvider.java112
-rw-r--r--main/src/cgeo/geocaching/sensors/IGeoData.java5
-rw-r--r--main/src/cgeo/geocaching/settings/Settings.java11
-rw-r--r--main/src/cgeo/geocaching/sorting/PopularityRatioComparator.java3
-rw-r--r--main/src/cgeo/geocaching/sorting/SortActionProvider.java4
-rw-r--r--main/src/cgeo/geocaching/twitter/Twitter.java16
-rw-r--r--main/src/cgeo/geocaching/ui/DecryptTextClickListener.java77
-rw-r--r--main/src/cgeo/geocaching/ui/ImagesList.java2
-rw-r--r--main/src/cgeo/geocaching/ui/dialog/DateDialog.java6
-rw-r--r--main/src/cgeo/geocaching/ui/logs/LogsViewCreator.java5
-rw-r--r--main/src/cgeo/geocaching/utils/CryptUtils.java44
-rw-r--r--main/src/cgeo/geocaching/utils/JsonUtils.java20
-rw-r--r--main/src/cgeo/geocaching/utils/LeastRecentlyUsedSet.java79
-rw-r--r--main/src/cgeo/geocaching/utils/OOMDumpingUncaughtExceptionHandler.java7
-rw-r--r--main/src/cgeo/geocaching/utils/RxUtils.java67
-rw-r--r--main/thirdparty/android/support/v4/app/FragmentListActivity.java10
-rw-r--r--main/thirdparty/cgeo/org/kxml2/io/KXmlSerializer.java1
-rw-r--r--tests/src/cgeo/geocaching/CgeoApplicationTest.java6
-rw-r--r--tests/src/cgeo/geocaching/GeocacheTest.java2
-rw-r--r--tests/src/cgeo/geocaching/export/GpxSerializerTest.java2
-rw-r--r--tests/src/cgeo/geocaching/files/GPXImporterTest.java13
-rw-r--r--tests/src/cgeo/geocaching/test/AbstractResourceInstrumentationTestCase.java4
93 files changed, 1428 insertions, 1356 deletions
diff --git a/.idea/inspectionProfiles/c_geo_standards.xml b/.idea/inspectionProfiles/c_geo_standards.xml
index cf3d2fb..1f06821 100644
--- a/.idea/inspectionProfiles/c_geo_standards.xml
+++ b/.idea/inspectionProfiles/c_geo_standards.xml
@@ -17,61 +17,106 @@
<inspection_tool class="Annotator" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="AntMissingPropertiesFileInspection" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="AntResolveInspection" enabled="false" level="ERROR" enabled_by_default="false" />
+ <inspection_tool class="ArrayEquality" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ArraysAsListWithZeroOrOneArgument" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AssignmentToCatchBlockParameter" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AssignmentToMethodParameter" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoreTransformationOfOriginalParameter" value="false" />
</inspection_tool>
<inspection_tool class="AssignmentUsedAsCondition" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="BooleanMethodIsAlwaysInverted" enabled="false" level="WARNING" enabled_by_default="false" />
+ <inspection_tool class="BooleanMethodNameMustStartWithQuestion" enabled="false" level="TYPO" enabled_by_default="false">
+ <option name="ignoreBooleanMethods" value="false" />
+ <option name="ignoreInAnnotationInterface" value="true" />
+ <option name="onlyWarnOnBaseMethods" value="true" />
+ <option name="questionString" value="is,can,has,should,could,will,shall,check,contains,equals,add,put,remove,startsWith,endsWith,on,require" />
+ </inspection_tool>
+ <inspection_tool class="BusyWait" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="CStyleArrayDeclaration" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="CanBeFinal" enabled="false" level="WARNING" enabled_by_default="false">
<option name="REPORT_CLASSES" value="false" />
<option name="REPORT_METHODS" value="false" />
<option name="REPORT_FIELDS" value="true" />
</inspection_tool>
+ <inspection_tool class="CastConflictsWithInstanceof" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="CastToIncompatibleInterface" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ChainedEquality" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="CheckEmptyScriptTag" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CheckTagEmptyBody" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CheckValidXmlInScriptTagBody" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="ClassInTopLevelPackage" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ClassNameDiffersFromFileName" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ClassNamingConvention" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="m_regex" value="[A-Z][A-Za-z\d]*" />
+ <option name="m_minLength" value="3" />
+ <option name="m_maxLength" value="64" />
+ </inspection_tool>
+ <inspection_tool class="ClassNewInstance" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ClassOnlyUsedInOneModule" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ClassOnlyUsedInOnePackage" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
+ <inspection_tool class="CollectionAddedToSelf" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="CollectionsFieldAccessReplaceableByMethodCall" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ComparableImplementedButEqualsNotOverridden" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ConditionSignal" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ConditionalExpressionWithIdenticalBranches" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ConfusingElse" enabled="true" level="WARNING" enabled_by_default="true">
<option name="reportWhenNoStatementFollow" value="false" />
</inspection_tool>
+ <inspection_tool class="ConstantAssertCondition" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ConstantConditions" enabled="true" level="WARNING" enabled_by_default="true">
<option name="SUGGEST_NULLABLE_ANNOTATIONS" value="false" />
<option name="DONT_REPORT_TRUE_ASSERT_STATEMENTS" value="true" />
</inspection_tool>
+ <inspection_tool class="ConstantNamingConvention" enabled="false" level="WEAK WARNING" enabled_by_default="false">
+ <option name="onlyCheckImmutables" value="false" />
+ <option name="m_regex" value="[A-Z][A-Z_\d]*" />
+ <option name="m_minLength" value="3" />
+ <option name="m_maxLength" value="32" />
+ </inspection_tool>
+ <inspection_tool class="ConstantStringIntern" enabled="true" level="ERROR" enabled_by_default="true" />
+ <inspection_tool class="CovariantCompareTo" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="CovariantEquals" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="CyclomaticComplexity" enabled="false" level="WEAK WARNING" enabled_by_default="false">
+ <option name="m_limit" value="10" />
+ </inspection_tool>
<inspection_tool class="DefaultNotLastCaseInSwitch" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="Deprecation" enabled="true" level="WARNING" enabled_by_default="true">
<option name="IGNORE_INSIDE_DEPRECATED" value="true" />
</inspection_tool>
+ <inspection_tool class="DollarSignInName" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="DoubleLiteralMayBeFloatLiteral" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="DuplicateBooleanBranch" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="DuplicateCondition" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoreMethodCalls" value="false" />
</inspection_tool>
+ <inspection_tool class="DynamicRegexReplaceableByCompiledPattern" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="EmptyCatchBlock" enabled="false" level="WARNING" enabled_by_default="false">
<option name="m_includeComments" value="true" />
<option name="m_ignoreTestCases" value="true" />
<option name="m_ignoreIgnoreParameter" value="true" />
</inspection_tool>
<inspection_tool class="EmptyMethod" enabled="false" level="WARNING" enabled_by_default="false" />
+ <inspection_tool class="EmptySynchronizedStatement" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="EnumSwitchStatementWhichMissesCases" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoreSwitchStatementsWithDefault" value="true" />
</inspection_tool>
<inspection_tool class="EqualsAndHashcode" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ErrorRethrown" enabled="true" level="ERROR" enabled_by_default="true" />
+ <inspection_tool class="ExtendsThread" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="FallthruInSwitchStatement" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="FieldAccessedSynchronizedAndUnsynchronized" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="countGettersAndSetters" value="false" />
+ </inspection_tool>
<inspection_tool class="FieldCanBeLocal" enabled="true" level="ERROR" enabled_by_default="true" />
+ <inspection_tool class="FieldHidesSuperclassField" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="m_ignoreInvisibleFields" value="true" />
+ </inspection_tool>
<inspection_tool class="FieldMayBeStatic" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="FinalStaticMethod" enabled="false" level="WARNING" enabled_by_default="false" />
- <inspection_tool class="ForCanBeForeach" enabled="false" level="WARNING" enabled_by_default="false">
- <option name="REPORT_INDEXED_LOOP" value="true" />
- <option name="ignoreUntypedCollections" value="false" />
- </inspection_tool>
<inspection_tool class="ForLoopReplaceableByWhile" enabled="true" level="WARNING" enabled_by_default="true">
<option name="m_ignoreLoopsWithoutConditions" value="false" />
</inspection_tool>
+ <inspection_tool class="ForLoopThatDoesntUseLoopVariable" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ForLoopWithMissingComponent" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoreCollectionLoops" value="false" />
</inspection_tool>
@@ -108,7 +153,28 @@
</inspection_tool>
<inspection_tool class="InfiniteLoopStatement" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="InnerClassMayBeStatic" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="InstanceMethodNamingConvention" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="m_regex" value="[a-z][A-Za-z\d]*" />
+ <option name="m_minLength" value="3" />
+ <option name="m_maxLength" value="32" />
+ </inspection_tool>
+ <inspection_tool class="InstanceVariableNamingConvention" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="m_regex" value="[a-z][A-Za-z\d]*" />
+ <option name="m_minLength" value="2" />
+ <option name="m_maxLength" value="30" />
+ </inspection_tool>
+ <inspection_tool class="InstanceofCatchParameter" enabled="true" level="ERROR" enabled_by_default="true" />
+ <inspection_tool class="InstanceofIncompatibleInterface" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="InstanceofThis" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="InstantiationOfUtilityClass" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="IntLiteralMayBeLongLiteral" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="InterfaceNamingConvention" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="m_regex" value="[A-Z][A-Za-z\d]*" />
+ <option name="m_minLength" value="3" />
+ <option name="m_maxLength" value="64" />
+ </inspection_tool>
+ <inspection_tool class="IteratorHasNextCallsIteratorNext" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="IteratorNextDoesNotThrowNoSuchElementException" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="JavaDoc" enabled="false" level="WARNING" enabled_by_default="false">
<option name="TOP_LEVEL_CLASS_OPTIONS">
<value>
@@ -141,10 +207,23 @@
<option name="myAdditionalJavadocTags" value="" />
</inspection_tool>
<inspection_tool class="JavadocReference" enabled="false" level="ERROR" enabled_by_default="false" />
+ <inspection_tool class="KeySetIterationMayUseEntrySet" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="LengthOneStringInIndexOf" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ListIndexOfReplaceableByContains" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ListenerMayUseAdapter" enabled="true" level="WARNING" enabled_by_default="true">
<option name="checkForEmptyMethods" value="true" />
</inspection_tool>
+ <inspection_tool class="LocalVariableHidingMemberVariable" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="m_ignoreInvisibleFields" value="true" />
+ <option name="m_ignoreStaticMethods" value="true" />
+ </inspection_tool>
+ <inspection_tool class="LocalVariableNamingConvention" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="m_ignoreForLoopParameters" value="true" />
+ <option name="m_ignoreCatchParameters" value="true" />
+ <option name="m_regex" value="[a-z][A-Za-z\d]*" />
+ <option name="m_minLength" value="2" />
+ <option name="m_maxLength" value="30" />
+ </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" />
@@ -153,10 +232,26 @@
<option name="ignoreIterators" value="false" />
</inspection_tool>
<inspection_tool class="LoopWithImplicitTerminationCondition" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="MapReplaceableByEnumMap" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="MethodCanBeVariableArityMethod" enabled="false" level="WARNING" enabled_by_default="false">
+ <option name="ignoreByteAndShortArrayParameters" value="true" />
+ <option name="ignoreOverridingMethods" value="true" />
+ </inspection_tool>
+ <inspection_tool class="MethodCoupling" enabled="false" level="WEAK WARNING" enabled_by_default="false">
+ <option name="m_includeJavaClasses" value="false" />
+ <option name="m_includeLibraryClasses" value="false" />
+ <option name="m_limit" value="10" />
+ </inspection_tool>
<inspection_tool class="MethodMayBeStatic" enabled="true" level="ERROR" enabled_by_default="true">
<option name="m_onlyPrivateOrFinal" value="false" />
<option name="m_ignoreEmptyMethods" value="true" />
</inspection_tool>
+ <inspection_tool class="MethodMayBeSynchronized" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="MethodNamesDifferOnlyByCase" enabled="true" level="ERROR" enabled_by_default="true" />
+ <inspection_tool class="MethodOverloadsParentMethod" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="MethodOverridesPackageLocalMethod" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="MethodOverridesPrivateMethod" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="MethodOverridesStaticMethod" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="MismatchedCollectionQueryUpdate" enabled="false" level="WARNING" enabled_by_default="false">
<option name="queryNames">
<value />
@@ -169,11 +264,35 @@
<option name="ignoreObjectMethods" value="true" />
<option name="ignoreAnonymousClassMethods" value="false" />
</inspection_tool>
+ <inspection_tool class="MisspelledCompareTo" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="MisspelledEquals" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="MisspelledHashcode" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="MisspelledToString" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="NakedNotify" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="NegatedIfElse" enabled="false" level="WARNING" enabled_by_default="false">
<option name="m_ignoreNegatedNullComparison" value="true" />
<option name="m_ignoreNegatedZeroComparison" value="true" />
</inspection_tool>
+ <inspection_tool class="NestedSynchronizedStatement" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="NestingDepth" enabled="false" level="WEAK WARNING" enabled_by_default="false">
+ <option name="m_limit" value="5" />
+ </inspection_tool>
+ <inspection_tool class="NonAtomicOperationOnVolatileField" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="NonBooleanMethodNameMayNotStartWithQuestion" enabled="true" level="TYPO" enabled_by_default="true">
+ <option name="questionString" value="is,can,has,should,could,will,shall,contains,equals,startsWith,endsWith" />
+ <option name="ignoreBooleanMethods" value="false" />
+ <option name="onlyWarnOnBaseMethods" value="true" />
+ </inspection_tool>
+ <inspection_tool class="NonCommentSourceStatements" enabled="false" level="WEAK WARNING" enabled_by_default="false">
+ <option name="m_limit" value="30" />
+ </inspection_tool>
+ <inspection_tool class="NonExceptionNameEndsWithException" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="NonFinalFieldInEnum" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="NonShortCircuitBoolean" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="NonSynchronizedMethodOverridesSynchronizedMethod" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="NotifyCalledOnCondition" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="NotifyNotInSynchronizedContext" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="NotifyWithoutCorrespondingWait" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="NullableProblems" enabled="true" level="ERROR" enabled_by_default="true">
<option name="REPORT_NULLABLE_METHOD_OVERRIDES_NOTNULL" value="true" />
<option name="REPORT_NOT_ANNOTATED_METHOD_OVERRIDES_NOTNULL" value="true" />
@@ -184,20 +303,49 @@
<option name="REPORT_ANNOTATION_NOT_PROPAGATED_TO_OVERRIDERS" value="true" />
<option name="REPORT_NULLS_PASSED_TO_NON_ANNOTATED_METHOD" value="true" />
</inspection_tool>
- <inspection_tool class="ObjectEquality" enabled="true" level="WARNING" enabled_by_default="true">
- <option name="m_ignoreEnums" value="true" />
- <option name="m_ignoreClassObjects" value="false" />
- <option name="m_ignorePrivateConstructors" value="false" />
- </inspection_tool>
+ <inspection_tool class="ObjectNotify" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ObjectToString" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ObsoleteCollection" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoreRequiredObsoleteCollectionTypes" value="false" />
</inspection_tool>
+ <inspection_tool class="OverloadedMethodsWithSameNumberOfParameters" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="ignoreInconvertibleTypes" value="true" />
+ </inspection_tool>
+ <inspection_tool class="PackageNamingConvention" enabled="true" level="TYPO" enabled_by_default="true">
+ <option name="m_regex" value="[a-z]*" />
+ <option name="m_minLength" value="2" />
+ <option name="m_maxLength" value="16" />
+ </inspection_tool>
+ <inspection_tool class="ParameterHidingMemberVariable" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="m_ignoreInvisibleFields" value="true" />
+ <option name="m_ignoreStaticMethodParametersHidingInstanceFields" value="true" />
+ <option name="m_ignoreForConstructors" value="true" />
+ <option name="m_ignoreForPropertySetters" value="true" />
+ <option name="m_ignoreForAbstractMethods" value="false" />
+ </inspection_tool>
+ <inspection_tool class="ParameterNameDiffersFromOverriddenParameter" enabled="false" level="WEAK WARNING" enabled_by_default="false">
+ <option name="m_ignoreSingleCharacterNames" value="false" />
+ <option name="m_ignoreOverridesOfLibraryMethods" value="false" />
+ </inspection_tool>
+ <inspection_tool class="ParameterNamingConvention" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="m_regex" value="[a-z][A-Za-z\d]*" />
+ <option name="m_minLength" value="2" />
+ <option name="m_maxLength" value="30" />
+ </inspection_tool>
<inspection_tool class="PointlessArithmeticExpression" enabled="false" level="WARNING" enabled_by_default="false">
<option name="m_ignoreExpressionsContainingConstants" value="false" />
</inspection_tool>
<inspection_tool class="PointlessIndexOfComparison" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PointlessNullCheck" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ProtectedMemberInFinalClass" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="PublicFieldAccessedInSynchronizedContext" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="QuestionableName" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="nameString" value="aa,abc,bad,bar,bar2,baz,baz1,baz2,baz3,bb,blah,bogus,bool,cc,dd,defau1t,dummy,dummy2,ee,fa1se,ff,foo,foo1,foo2,foo3,foobar,four,fred,fred1,fred2,gg,hh,hello,hello1,hello2,hello3,ii,nu11,one,silly,silly2,string,two,that,then,three,whi1e,var" />
+ </inspection_tool>
+ <inspection_tool class="RandomDoubleForRandomInteger" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="RedundantArrayCreation" enabled="false" level="WARNING" enabled_by_default="false" />
+ <inspection_tool class="RedundantStringFormatCall" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ReplaceAllDot" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ReplaceAssignmentWithOperatorAssignment" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoreLazyOperators" value="true" />
<option name="ignoreObscureOperators" value="false" />
@@ -212,40 +360,88 @@
<option name="m_reportCollectionMethods" value="true" />
<option name="m_ignorePrivateMethods" value="false" />
</inspection_tool>
+ <inspection_tool class="SafeLock" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="SameParameterValue" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SameReturnValue" enabled="false" level="WARNING" enabled_by_default="false" />
+ <inspection_tool class="SharedThreadLocalRandom" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="SignalWithoutCorrespondingAwait" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="SimplifiableEqualsExpression" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="SimplifiableIfStatement" enabled="false" level="WARNING" enabled_by_default="false" />
+ <inspection_tool class="Since15" enabled="true" level="ERROR" enabled_by_default="true">
+ <effectiveLL value="JDK_1_6" />
+ </inspection_tool>
<inspection_tool class="SizeReplaceableByIsEmpty" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="SleepWhileHoldingLock" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
<option name="processCode" value="true" />
<option name="processLiterals" value="true" />
<option name="processComments" value="true" />
</inspection_tool>
+ <inspection_tool class="StaticCallOnSubclass" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="StaticFieldReferenceOnSubclass" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="StaticMethodNamingConvention" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="m_regex" value="[a-z][A-Za-z\d]*" />
+ <option name="m_minLength" value="1" />
+ <option name="m_maxLength" value="64" />
+ </inspection_tool>
+ <inspection_tool class="StaticVariableNamingConvention" enabled="false" level="WARNING" enabled_by_default="false">
+ <option name="checkMutableFinals" value="false" />
+ <option name="m_regex" value="[a-z][A-Za-z\d]*" />
+ <option name="m_minLength" value="3" />
+ <option name="m_maxLength" value="30" />
+ </inspection_tool>
<inspection_tool class="StringBufferReplaceableByString" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="StringBufferToStringInConcatenation" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="StringConcatenationInFormatCall" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="StringConcatenationInMessageFormatCall" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="StringConcatenationMissingWhitespace" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="ignoreNonStringLiterals" value="true" />
+ </inspection_tool>
<inspection_tool class="StringConstructor" enabled="false" level="WARNING" enabled_by_default="false">
<option name="ignoreSubstringArguments" value="false" />
</inspection_tool>
- <inspection_tool class="SuspiciousMethodCalls" enabled="false" level="WARNING" enabled_by_default="false">
- <option name="REPORT_CONVERTIBLE_METHOD_CALLS" value="true" />
+ <inspection_tool class="StringEqualsEmptyString" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="StringReplaceableByStringBuffer" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="onlyWarnOnLoop" value="true" />
</inspection_tool>
+ <inspection_tool class="SubstringZero" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="SwitchStatementWithConfusingDeclaration" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="SwitchStatementWithTooFewBranches" enabled="true" level="WARNING" enabled_by_default="true">
<option name="m_limit" value="2" />
</inspection_tool>
- <inspection_tool class="SynchronizationOnLocalVariableOrMethodParameter" enabled="false" level="WARNING" enabled_by_default="false">
- <option name="reportLocalVariables" value="true" />
- <option name="reportMethodParameters" value="true" />
- </inspection_tool>
+ <inspection_tool class="SynchronizeOnLock" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="SynchronizedOnLiteralObject" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="SyntaxError" enabled="false" level="ERROR" enabled_by_default="false" />
+ <inspection_tool class="SystemGC" enabled="true" level="ERROR" enabled_by_default="true" />
<inspection_tool class="SystemOutErr" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="SystemRunFinalizersOnExit" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="TextLabelInSwitchStatement" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ThreadDeathRethrown" enabled="true" level="ERROR" enabled_by_default="true" />
+ <inspection_tool class="ThreadLocalNotStaticFinal" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ThreadPriority" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ThreadRun" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ThreadStartInConstruction" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ThreadStopSuspendResume" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ThreadWithDefaultRunMethod" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ThreadYield" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="ThreeNegationsPerMethod" enabled="false" level="WEAK WARNING" enabled_by_default="false">
+ <option name="m_ignoreInEquals" value="true" />
+ <option name="ignoreInAssert" value="false" />
+ </inspection_tool>
<inspection_tool class="TooBroadScope" enabled="true" level="WARNING" enabled_by_default="true">
<option name="m_allowConstructorAsInitializer" value="false" />
<option name="m_onlyLookAtBlocks" value="false" />
</inspection_tool>
+ <inspection_tool class="TrivialStringConcatenation" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="TryFinallyCanBeTryWithResources" enabled="false" level="WARNING" enabled_by_default="false" />
+ <inspection_tool class="TypeParameterNamingConvention" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="m_regex" value="[A-Z][A-Za-z\d]*" />
+ <option name="m_minLength" value="1" />
+ <option name="m_maxLength" value="16" />
+ </inspection_tool>
<inspection_tool class="UNCHECKED_WARNING" enabled="false" level="WARNING" enabled_by_default="false" />
+ <inspection_tool class="UnaryPlus" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="UnconditionalWait" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="UnnecessarilyQualifiedStaticallyImportedElement" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="UnnecessaryBlockStatement" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoreSwitchBranches" value="true" />
@@ -257,11 +453,16 @@
<inspection_tool class="UnnecessaryQualifierForThis" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="UnnecessarySemicolon" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnnecessarySuperConstructor" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="UnnecessaryUnaryMinus" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="UnusedAssignment" enabled="true" level="WARNING" enabled_by_default="true">
<option name="REPORT_PREFIX_EXPRESSIONS" value="false" />
<option name="REPORT_POSTFIX_EXPRESSIONS" value="false" />
<option name="REPORT_REDUNDANT_INITIALIZER" value="true" />
</inspection_tool>
+ <inspection_tool class="UnusedCatchParameter" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="m_ignoreCatchBlocksWithComments" value="false" />
+ <option name="m_ignoreTestCases" value="false" />
+ </inspection_tool>
<inspection_tool class="UnusedDeclaration" enabled="false" level="WARNING" enabled_by_default="false">
<option name="ADD_MAINS_TO_ENTRIES" value="true" />
<option name="ADD_APPLET_TO_ENTRIES" value="true" />
@@ -272,14 +473,26 @@
<inspection_tool class="UnusedParameters" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnusedProperty" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnusedReturnValue" enabled="false" level="WARNING" enabled_by_default="false" />
+ <inspection_tool class="UpperCaseFieldNameNotConstant" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="UseOfPropertiesAsHashtable" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="UtilityClassWithPublicConstructor" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="WaitCalledOnCondition" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="WaitNotInLoop" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="WaitNotInSynchronizedContext" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="WaitOrAwaitWithoutTimeout" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="WaitWhileHoldingTwoLocks" enabled="true" level="WARNING" enabled_by_default="true" />
+ <inspection_tool class="WaitWithoutCorrespondingNotify" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="WeakerAccess" enabled="false" level="WARNING" enabled_by_default="false">
<option name="SUGGEST_PACKAGE_LOCAL_FOR_MEMBERS" value="true" />
<option name="SUGGEST_PACKAGE_LOCAL_FOR_TOP_CLASSES" value="true" />
<option name="SUGGEST_PRIVATE_FOR_INNERS" value="false" />
</inspection_tool>
+ <inspection_tool class="WhileLoopSpinsOnField" enabled="true" level="WARNING" enabled_by_default="true">
+ <option name="ignoreNonEmtpyLoops" value="false" />
+ </inspection_tool>
<inspection_tool class="XmlDuplicatedId" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="XmlHighlighting" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="XmlUnboundNsPrefix" enabled="false" level="WARNING" enabled_by_default="false" />
+ <inspection_tool class="ZeroLengthArrayInitialization" enabled="true" level="WARNING" enabled_by_default="true" />
</profile>
</component> \ No newline at end of file
diff --git a/main/build.gradle b/main/build.gradle
index e4f60fe..325af71 100644
--- a/main/build.gradle
+++ b/main/build.gradle
@@ -28,6 +28,9 @@ gradle connectedCheck
def AAVersion = '3.0.1'
def RXVersion = '0.19.6'
+def JacksonCoreVersion = '2.4.1.1'
+def JacksonDatabindVersion = '2.4.1.3'
+def JacksonAnnotationsVersion = '2.4.1'
group = 'cgeo.geocaching'
version = '0.0.1'
@@ -162,6 +165,10 @@ dependencies {
compile "com.netflix.rxjava:rxjava-android:$RXVersion"
compile "com.netflix.rxjava:rxjava-async-util:$RXVersion"
+ compile "com.fasterxml.jackson.core:jackson-core:$JacksonCoreVersion"
+ compile "com.fasterxml.jackson.core:jackson-databind:$JacksonDatabindVersion"
+ compile "com.fasterxml.jackson.core:jackson-annotations:$JacksonAnnotationsVersion"
+
//TEST
//compile files('compile-libs/androidannotations-3.0.1.jar')
//compile files('compile-libs/findbugs-ant.jar')
@@ -357,4 +364,4 @@ task addTest {
// always do the addtest on prebuild
gradle.projectsEvaluated {
preBuild.dependsOn(addTest)
-}*/ \ No newline at end of file
+}*/
diff --git a/main/libs/jackson-annotations-2.4.1.jar b/main/libs/jackson-annotations-2.4.1.jar
new file mode 100644
index 0000000..decd2d1
--- /dev/null
+++ b/main/libs/jackson-annotations-2.4.1.jar
Binary files differ
diff --git a/main/libs/jackson-annotations-2.4.1.jar.properties b/main/libs/jackson-annotations-2.4.1.jar.properties
new file mode 100644
index 0000000..710f903
--- /dev/null
+++ b/main/libs/jackson-annotations-2.4.1.jar.properties
@@ -0,0 +1,2 @@
+src=src/jackson-annotations-2.4.1-sources.jar
+doc=src/jackson-annotations-2.4.1-javadoc.jar
diff --git a/main/libs/jackson-core-2.4.1.1.jar b/main/libs/jackson-core-2.4.1.1.jar
new file mode 100644
index 0000000..5fe10ae
--- /dev/null
+++ b/main/libs/jackson-core-2.4.1.1.jar
Binary files differ
diff --git a/main/libs/jackson-core-2.4.1.1.jar.properties b/main/libs/jackson-core-2.4.1.1.jar.properties
new file mode 100644
index 0000000..0a3222e
--- /dev/null
+++ b/main/libs/jackson-core-2.4.1.1.jar.properties
@@ -0,0 +1,2 @@
+src=src/jackson-core-2.4.1.1-sources.jar
+doc=src/jackson-core-2.4.1.1-javadoc.jar
diff --git a/main/libs/jackson-databind-2.4.1.3.jar b/main/libs/jackson-databind-2.4.1.3.jar
new file mode 100644
index 0000000..231bd1f
--- /dev/null
+++ b/main/libs/jackson-databind-2.4.1.3.jar
Binary files differ
diff --git a/main/libs/jackson-databind-2.4.1.3.jar.properties b/main/libs/jackson-databind-2.4.1.3.jar.properties
new file mode 100644
index 0000000..f4cc029
--- /dev/null
+++ b/main/libs/jackson-databind-2.4.1.3.jar.properties
@@ -0,0 +1,2 @@
+src=src/jackson-databind-2.4.1.3-sources.jar
+doc=src/jackson-databind-2.4.1.3-javadoc.jar
diff --git a/main/libs/src/jackson-annotations-2.4.1-javadoc.jar b/main/libs/src/jackson-annotations-2.4.1-javadoc.jar
new file mode 100644
index 0000000..40bb9d2
--- /dev/null
+++ b/main/libs/src/jackson-annotations-2.4.1-javadoc.jar
Binary files differ
diff --git a/main/libs/src/jackson-annotations-2.4.1-sources.jar b/main/libs/src/jackson-annotations-2.4.1-sources.jar
new file mode 100644
index 0000000..f9e50a4
--- /dev/null
+++ b/main/libs/src/jackson-annotations-2.4.1-sources.jar
Binary files differ
diff --git a/main/libs/src/jackson-core-2.4.1.1-javadoc.jar b/main/libs/src/jackson-core-2.4.1.1-javadoc.jar
new file mode 100644
index 0000000..cfae85e
--- /dev/null
+++ b/main/libs/src/jackson-core-2.4.1.1-javadoc.jar
Binary files differ
diff --git a/main/libs/src/jackson-core-2.4.1.1-sources.jar b/main/libs/src/jackson-core-2.4.1.1-sources.jar
new file mode 100644
index 0000000..0647e10
--- /dev/null
+++ b/main/libs/src/jackson-core-2.4.1.1-sources.jar
Binary files differ
diff --git a/main/libs/src/jackson-databind-2.4.1.3-javadoc.jar b/main/libs/src/jackson-databind-2.4.1.3-javadoc.jar
new file mode 100644
index 0000000..5bab5af
--- /dev/null
+++ b/main/libs/src/jackson-databind-2.4.1.3-javadoc.jar
Binary files differ
diff --git a/main/libs/src/jackson-databind-2.4.1.3-sources.jar b/main/libs/src/jackson-databind-2.4.1.3-sources.jar
new file mode 100644
index 0000000..1bab3a5
--- /dev/null
+++ b/main/libs/src/jackson-databind-2.4.1.3-sources.jar
Binary files differ
diff --git a/main/proguard-project.txt b/main/proguard-project.txt
index 74b8aa2..c6e67fd 100644
--- a/main/proguard-project.txt
+++ b/main/proguard-project.txt
@@ -21,6 +21,9 @@
# rxjava internal references sun.misc.Unsafe
-dontwarn sun.misc.Unsafe
+# jackson internal references
+-dontwarn org.w3c.dom.bootstrap.DOMImplementationRegistry
+
#-dontnote org.apache.commons.logging.**
-keep public class cgeo.geocaching.*
diff --git a/main/project/libraries/update-libs.sh b/main/project/libraries/update-libs.sh
index f2e9ced..bdf25c4 100755
--- a/main/project/libraries/update-libs.sh
+++ b/main/project/libraries/update-libs.sh
@@ -2,6 +2,9 @@
#
RXJAVA=0.19.6
+JACKSONCORE=2.4.1.1
+JACKSONDATABIND=2.4.1.3
+JACKSONANNOTATIONS=2.4.1
cd $(git rev-parse --show-toplevel)/main/libs
@@ -31,3 +34,10 @@ updatelib com/netflix/rxjava rxjava-core $RXJAVA
updatelib com/netflix/rxjava rxjava-android $RXJAVA
updatelib com/netflix/rxjava rxjava-async-util $RXJAVA
fixgradle RXVersion $RXJAVA
+
+updatelib com/fasterxml/jackson/core jackson-core $JACKSONCORE
+fixgradle JacksonCoreVersion $JACKSONCORE
+updatelib com/fasterxml/jackson/core jackson-databind $JACKSONDATABIND
+fixgradle JacksonDatabindVersion $JACKSONDATABIND
+updatelib com/fasterxml/jackson/core jackson-annotations $JACKSONANNOTATIONS
+fixgradle JacksonAnnotationsVersion $JACKSONANNOTATIONS
diff --git a/main/res/values/changelog_master.xml b/main/res/values/changelog_master.xml
index 1e3c3d4..9b35112 100644
--- a/main/res/values/changelog_master.xml
+++ b/main/res/values/changelog_master.xml
@@ -2,5 +2,8 @@
<resources>
<!-- changelog for the master branch -->
<string name="changelog_master" translatable="false">
+ <b>Next feature release:</b>\n
+ \n
+ \n
</string>
</resources>
diff --git a/main/res/values/preference_keys.xml b/main/res/values/preference_keys.xml
index 72d7c61..5189cc5 100644
--- a/main/res/values/preference_keys.xml
+++ b/main/res/values/preference_keys.xml
@@ -108,7 +108,6 @@
<string name="pref_cookiestore">cookiestore</string>
<string name="pref_lastdetailspage">lastdetailspage</string>
<string name="pref_livemapstrategy">livemapstrategy</string>
- <string name="pref_hidelivemaphint">hidelivemaphint</string>
<string name="pref_livemaphintshowcount">livemaphintshowcount</string>
<string name="pref_settingsversion">settingsversion</string>
<string name="pref_trackableaction">trackableaction</string>
diff --git a/main/src/cgeo/geocaching/AbstractDialogFragment.java b/main/src/cgeo/geocaching/AbstractDialogFragment.java
index 4025347..6f64146 100644
--- a/main/src/cgeo/geocaching/AbstractDialogFragment.java
+++ b/main/src/cgeo/geocaching/AbstractDialogFragment.java
@@ -42,7 +42,6 @@ import android.widget.ImageView;
import android.widget.TextView;
public abstract class AbstractDialogFragment extends DialogFragment implements CacheMenuHandler.ActivityInterface, PopupMenu.OnMenuItemClickListener, MenuItem.OnMenuItemClickListener {
- protected CgeoApplication app = null;
protected Resources res = null;
protected String geocode;
protected CacheDetailsCreator details;
@@ -61,7 +60,6 @@ public abstract class AbstractDialogFragment extends DialogFragment implements C
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
res = getResources();
- app = (CgeoApplication) getActivity().getApplication();
setHasOptionsMenu(true);
}
diff --git a/main/src/cgeo/geocaching/CacheDetailActivity.java b/main/src/cgeo/geocaching/CacheDetailActivity.java
index dff8e09..7d13cf4 100644
--- a/main/src/cgeo/geocaching/CacheDetailActivity.java
+++ b/main/src/cgeo/geocaching/CacheDetailActivity.java
@@ -617,13 +617,6 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
}
/**
- * Wrapper for the referenced method in the xml-layout.
- */
- public void goDefaultNavigation(@SuppressWarnings("unused") final View view) {
- startDefaultNavigation();
- }
-
- /**
* referenced from XML view
*/
public void showNavigationMenu(@SuppressWarnings("unused") final View view) {
@@ -893,9 +886,9 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
public void call(final Integer selectedListId) {
storeCache(selectedListId, new StoreCacheHandler(CacheDetailActivity.this, progress));
}
- }, true, StoredList.TEMPORARY_LIST_ID);
+ }, true, StoredList.TEMPORARY_LIST.id);
} else {
- storeCache(StoredList.TEMPORARY_LIST_ID, new StoreCacheHandler(this, progress));
+ storeCache(StoredList.TEMPORARY_LIST.id, new StoreCacheHandler(this, progress));
}
}
diff --git a/main/src/cgeo/geocaching/CacheListActivity.java b/main/src/cgeo/geocaching/CacheListActivity.java
index 9d15e47..0ef587b 100644
--- a/main/src/cgeo/geocaching/CacheListActivity.java
+++ b/main/src/cgeo/geocaching/CacheListActivity.java
@@ -130,7 +130,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA
private int detailTotal = 0;
private int detailProgress = 0;
private long detailProgressTime = 0L;
- private int listId = StoredList.TEMPORARY_LIST_ID; // Only meaningful for the OFFLINE type
+ private int listId = StoredList.TEMPORARY_LIST.id; // Only meaningful for the OFFLINE type
private final GeoDirHandler geoDirHandler = new GeoDirHandler() {
@Override
@@ -1080,11 +1080,11 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA
}
refreshStoredInternal(caches);
}
- }, true, StoredList.TEMPORARY_LIST_ID, newListName);
+ }, true, StoredList.TEMPORARY_LIST.id, newListName);
} else {
if (type != CacheListType.OFFLINE) {
for (final Geocache geocache : caches) {
- if (geocache.getListId() == StoredList.TEMPORARY_LIST_ID) {
+ if (geocache.getListId() == StoredList.TEMPORARY_LIST.id) {
geocache.setListId(StoredList.STANDARD_LIST_ID);
}
}
@@ -1592,7 +1592,7 @@ public class CacheListActivity extends AbstractListActivity implements FilteredA
}
if (listId == PseudoList.ALL_LIST.id) {
title = res.getString(R.string.list_all_lists);
- } else if (listId <= StoredList.TEMPORARY_LIST_ID) {
+ } else if (listId <= StoredList.TEMPORARY_LIST.id) {
listId = StoredList.STANDARD_LIST_ID;
title = res.getString(R.string.stored_caches_button);
} else {
diff --git a/main/src/cgeo/geocaching/CachePopupFragment.java b/main/src/cgeo/geocaching/CachePopupFragment.java
index b2af12c..995fea2 100644
--- a/main/src/cgeo/geocaching/CachePopupFragment.java
+++ b/main/src/cgeo/geocaching/CachePopupFragment.java
@@ -17,8 +17,6 @@ import rx.functions.Action0;
import rx.functions.Action1;
import rx.schedulers.Schedulers;
-import android.content.Context;
-import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.Handler;
@@ -135,9 +133,9 @@ public class CachePopupFragment extends AbstractDialogFragment {
public void call(final Integer selectedListId) {
storeCache(selectedListId);
}
- }, true, StoredList.TEMPORARY_LIST_ID);
+ }, true, StoredList.TEMPORARY_LIST.id);
} else {
- storeCache(StoredList.TEMPORARY_LIST_ID);
+ storeCache(StoredList.TEMPORARY_LIST.id);
}
}
@@ -212,12 +210,6 @@ public class CachePopupFragment extends AbstractDialogFragment {
getActivity().finish();
}
- public static void startActivity(final Context context, final String geocode) {
- final Intent popupIntent = new Intent(context, CachePopup.class);
- popupIntent.putExtra(Intents.EXTRA_GEOCODE, geocode);
- context.startActivity(popupIntent);
- }
-
@Override
protected Geopoint getCoordinates() {
if (cache == null) {
diff --git a/main/src/cgeo/geocaching/CgeoApplication.java b/main/src/cgeo/geocaching/CgeoApplication.java
index 863dcdd..269c1b6 100644
--- a/main/src/cgeo/geocaching/CgeoApplication.java
+++ b/main/src/cgeo/geocaching/CgeoApplication.java
@@ -2,6 +2,8 @@ package cgeo.geocaching;
import cgeo.geocaching.sensors.DirectionProvider;
import cgeo.geocaching.sensors.GeoDataProvider;
+import cgeo.geocaching.sensors.GpsStatusProvider;
+import cgeo.geocaching.sensors.GpsStatusProvider.Status;
import cgeo.geocaching.sensors.IGeoData;
import cgeo.geocaching.utils.Log;
import cgeo.geocaching.utils.OOMDumpingUncaughtExceptionHandler;
@@ -23,6 +25,7 @@ public class CgeoApplication extends Application {
private static CgeoApplication instance;
private Observable<IGeoData> geoDataObservable;
private Observable<Float> directionObservable;
+ private Observable<Status> gpsStatusObservable;
private volatile IGeoData currentGeo = null;
private volatile float currentDirection = 0.0f;
@@ -59,12 +62,7 @@ public class CgeoApplication extends Application {
final Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey");
menuKeyField.setAccessible(true);
menuKeyField.setBoolean(config, false);
- } catch (final IllegalArgumentException e) {
- // ignore
- } catch (final NoSuchFieldException e) {
- // ignore
- } catch (final IllegalAccessException e) {
- // ignore
+ } catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException ignore) {
}
// ensure initialization of lists
DataStore.getLists();
@@ -104,6 +102,14 @@ public class CgeoApplication extends Application {
return directionObservable;
}
+ public synchronized Observable<Status> gpsStatusObservable() {
+ if (gpsStatusObservable == null) {
+ final ConnectableObservable<Status> onDemand = GpsStatusProvider.create(this).replay(1);
+ gpsStatusObservable = onDemand.refCount();
+ }
+ return gpsStatusObservable;
+ }
+
public IGeoData currentGeo() {
return currentGeo != null ? currentGeo : geoDataObservable().toBlocking().first();
}
diff --git a/main/src/cgeo/geocaching/CompassActivity.java b/main/src/cgeo/geocaching/CompassActivity.java
index 025d938..7b5ae35 100644
--- a/main/src/cgeo/geocaching/CompassActivity.java
+++ b/main/src/cgeo/geocaching/CompassActivity.java
@@ -10,6 +10,7 @@ import cgeo.geocaching.geopoint.Units;
import cgeo.geocaching.maps.CGeoMap;
import cgeo.geocaching.sensors.DirectionProvider;
import cgeo.geocaching.sensors.GeoDirHandler;
+import cgeo.geocaching.sensors.GpsStatusProvider.Status;
import cgeo.geocaching.sensors.IGeoData;
import cgeo.geocaching.settings.Settings;
import cgeo.geocaching.speech.SpeechService;
@@ -21,6 +22,9 @@ import cgeo.geocaching.utils.Log;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.jdt.annotation.Nullable;
+import rx.android.schedulers.AndroidSchedulers;
+import rx.functions.Action1;
+
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
@@ -118,7 +122,8 @@ public class CompassActivity extends AbstractActionBarActivity {
@Override
public void onResume() {
- super.onResume(geoDirHandler.start(GeoDirHandler.UPDATE_GEODIR));
+ super.onResume(geoDirHandler.start(GeoDirHandler.UPDATE_GEODIR),
+ app.gpsStatusObservable().observeOn(AndroidSchedulers.mainThread()).subscribe(gpsStatusHandler));
}
@Override
@@ -259,16 +264,22 @@ public class CompassActivity extends AbstractActionBarActivity {
headingView.setText(Math.round(cacheHeading) + "°");
}
+ private final Action1<Status> gpsStatusHandler = new Action1<Status>() {
+ @Override
+ public void call(final Status gpsStatus) {
+ if (gpsStatus.satellitesVisible >= 0) {
+ navSatellites.setText(res.getString(R.string.loc_sat) + ": " + gpsStatus.satellitesFixed + "/" + gpsStatus.satellitesVisible);
+ } else {
+ navSatellites.setText("");
+ }
+ }
+ };
+
private final GeoDirHandler geoDirHandler = new GeoDirHandler() {
@Override
public void updateGeoDir(final IGeoData geo, final float dir) {
try {
if (geo.getCoords() != null) {
- if (geo.getSatellitesVisible() >= 0) {
- navSatellites.setText(res.getString(R.string.loc_sat) + ": " + geo.getSatellitesFixed() + "/" + geo.getSatellitesVisible());
- } else {
- navSatellites.setText("");
- }
navType.setText(res.getString(geo.getLocationProvider().resourceId));
if (geo.getAccuracy() >= 0) {
diff --git a/main/src/cgeo/geocaching/DataStore.java b/main/src/cgeo/geocaching/DataStore.java
index e236f8f..4f4eaec 100644
--- a/main/src/cgeo/geocaching/DataStore.java
+++ b/main/src/cgeo/geocaching/DataStore.java
@@ -58,6 +58,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
+import java.util.EnumMap;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
@@ -1009,7 +1010,7 @@ public class DataStore {
}
synchronized (listId) {
listId.bindString(1, value);
- return listId.simpleQueryForLong() != StoredList.TEMPORARY_LIST_ID;
+ return listId.simpleQueryForLong() != StoredList.TEMPORARY_LIST.id;
}
} catch (final SQLiteDoneException e) {
// Do nothing, it only means we have no information on the cache
@@ -1041,27 +1042,6 @@ public class DataStore {
return null;
}
- public static String getCacheidForGeocode(final String geocode) {
- if (StringUtils.isBlank(geocode)) {
- return null;
- }
- init();
-
- try {
- final SQLiteStatement description = PreparedStatements.getCacheIdOfGeocode();
- synchronized (description) {
- description.bindString(1, geocode);
- return description.simpleQueryForString();
- }
- } catch (final SQLiteDoneException e) {
- // Do nothing, it only means we have no information on the cache
- } catch (final Exception e) {
- Log.e("DataStore.getCacheidForGeocode", e);
- }
-
- return null;
- }
-
/**
* Save/store a cache to the CacheCache
*
@@ -1970,7 +1950,7 @@ public class DataStore {
init();
- final Map<LogType, Integer> logCounts = new HashMap<>();
+ final Map<LogType, Integer> logCounts = new EnumMap<>(LogType.class);
final Cursor cursor = database.query(
dbTableLogCount,
@@ -3003,10 +2983,6 @@ public class DataStore {
return getStatement("listFromGeocode", "SELECT reason FROM " + dbTableCaches + " WHERE guid = ?");
}
- private static SQLiteStatement getCacheIdOfGeocode() {
- return getStatement("cacheIdFromGeocode", "SELECT cacheid FROM " + dbTableCaches + " WHERE geocode = ?");
- }
-
private static SQLiteStatement getGeocodeOfGuid() {
return getStatement("geocodeFromGuid", "SELECT geocode FROM " + dbTableCaches + " WHERE guid = ?");
}
@@ -3018,7 +2994,7 @@ public class DataStore {
}
public static void markDropped(final List<Geocache> caches) {
- moveToList(caches, StoredList.TEMPORARY_LIST_ID);
+ moveToList(caches, StoredList.TEMPORARY_LIST.id);
}
public static Viewport getBounds(final String geocode) {
diff --git a/main/src/cgeo/geocaching/Geocache.java b/main/src/cgeo/geocaching/Geocache.java
index e0daae1..19082d9 100644
--- a/main/src/cgeo/geocaching/Geocache.java
+++ b/main/src/cgeo/geocaching/Geocache.java
@@ -12,11 +12,9 @@ import cgeo.geocaching.connector.gc.GCConnector;
import cgeo.geocaching.connector.gc.GCConstants;
import cgeo.geocaching.connector.gc.Tile;
import cgeo.geocaching.connector.gc.UncertainProperty;
-import cgeo.geocaching.enumerations.CacheAttribute;
import cgeo.geocaching.enumerations.CacheSize;
import cgeo.geocaching.enumerations.CacheType;
import cgeo.geocaching.enumerations.LoadFlags;
-import cgeo.geocaching.enumerations.LoadFlags.LoadFlag;
import cgeo.geocaching.enumerations.LoadFlags.RemoveFlag;
import cgeo.geocaching.enumerations.LoadFlags.SaveFlag;
import cgeo.geocaching.enumerations.LogType;
@@ -69,8 +67,8 @@ import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
+import java.util.EnumMap;
import java.util.EnumSet;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.LinkedList;
@@ -88,7 +86,7 @@ public class Geocache implements ICache, IWaypoint {
private long updated = 0;
private long detailedUpdate = 0;
private long visitedDate = 0;
- private int listId = StoredList.TEMPORARY_LIST_ID;
+ private int listId = StoredList.TEMPORARY_LIST.id;
private boolean detailed = false;
private String geocode = "";
private String cacheId = "";
@@ -149,7 +147,7 @@ public class Geocache implements ICache, IWaypoint {
private List<Image> spoilers = null;
private List<Trackable> inventory = null;
- private Map<LogType, Integer> logCounts = new HashMap<>();
+ private Map<LogType, Integer> logCounts = new EnumMap<>(LogType.class);
private boolean userModifiedCoords = false;
// temporary values
private boolean statusChecked = false;
@@ -165,7 +163,7 @@ public class Geocache implements ICache, IWaypoint {
// Images whose URL contains one of those patterns will not be available on the Images tab
// for opening into an external application.
- private final String[] NO_EXTERNAL = new String[]{"geocheck.org"};
+ private final static String[] NO_EXTERNAL = new String[]{"geocheck.org"};
/**
* Create a new cache. To be used everywhere except for the GPX parser
@@ -251,7 +249,7 @@ public class Geocache implements ICache, IWaypoint {
if (visitedDate == 0) {
visitedDate = other.visitedDate;
}
- if (listId == StoredList.TEMPORARY_LIST_ID) {
+ if (listId == StoredList.TEMPORARY_LIST.id) {
listId = other.listId;
}
if (StringUtils.isBlank(geocode)) {
@@ -1432,7 +1430,7 @@ public class Geocache implements ICache, IWaypoint {
}
public void store(final CancellableHandler handler) {
- store(StoredList.TEMPORARY_LIST_ID, handler);
+ store(StoredList.TEMPORARY_LIST.id, handler);
}
public void store(final int listId, final CancellableHandler handler) {
@@ -1627,7 +1625,7 @@ public class Geocache implements ICache, IWaypoint {
return null;
}
- if (!forceReload && listId == StoredList.TEMPORARY_LIST_ID && (DataStore.isOffline(geocode, guid) || DataStore.isThere(geocode, guid, true, true))) {
+ if (!forceReload && listId == StoredList.TEMPORARY_LIST.id && (DataStore.isOffline(geocode, guid) || DataStore.isThere(geocode, guid, true, true))) {
final SearchResult search = new SearchResult();
final String realGeocode = StringUtils.isNotBlank(geocode) ? geocode : DataStore.getGeocodeForGuid(guid);
search.addGeocode(realGeocode);
@@ -1693,22 +1691,6 @@ public class Geocache implements ICache, IWaypoint {
return null;
}
- /**
- * check whether the cache has a given attribute
- *
- * @param attribute
- * @param yes
- * true if we are looking for the attribute_yes version, false for the attribute_no version
- * @return
- */
- public boolean hasAttribute(final CacheAttribute attribute, final boolean yes) {
- Geocache fullCache = DataStore.loadCache(getGeocode(), EnumSet.of(LoadFlag.ATTRIBUTES));
- if (fullCache == null) {
- fullCache = this;
- }
- return fullCache.getAttributes().contains(attribute.getAttributeName(yes));
- }
-
public boolean hasStaticMap() {
return StaticMapsProvider.hasStaticMap(this);
}
diff --git a/main/src/cgeo/geocaching/GpxFileListActivity.java b/main/src/cgeo/geocaching/GpxFileListActivity.java
index dae52c4..3da4927 100644
--- a/main/src/cgeo/geocaching/GpxFileListActivity.java
+++ b/main/src/cgeo/geocaching/GpxFileListActivity.java
@@ -1,63 +1,63 @@
-package cgeo.geocaching;
-
-import cgeo.geocaching.connector.ConnectorFactory;
-import cgeo.geocaching.connector.IConnector;
-import cgeo.geocaching.files.AbstractFileListActivity;
-import cgeo.geocaching.files.GPXImporter;
-import cgeo.geocaching.list.StoredList;
-import cgeo.geocaching.settings.Settings;
-import cgeo.geocaching.ui.GPXListAdapter;
-
-import org.apache.commons.lang3.StringUtils;
-
-import android.app.Activity;
-import android.content.Intent;
-
-import java.io.File;
-import java.util.Collections;
-import java.util.List;
-
-public class GpxFileListActivity extends AbstractFileListActivity<GPXListAdapter> {
-
- public GpxFileListActivity() {
- super(new String[] { "gpx", "loc", "zip" });
- }
-
- @Override
- protected GPXListAdapter getAdapter(List<File> files) {
- return new GPXListAdapter(this, files);
- }
-
- @Override
- protected List<File> getBaseFolders() {
- return Collections.singletonList(new File(Settings.getGpxImportDir()));
- }
-
- public static void startSubActivity(Activity fromActivity, int listId) {
- final Intent intent = new Intent(fromActivity, GpxFileListActivity.class);
- intent.putExtra(Intents.EXTRA_LIST_ID, StoredList.getConcreteList(listId));
- fromActivity.startActivityForResult(intent, 0);
- }
-
- @Override
- protected boolean filenameBelongsToList(final String filename) {
- if (super.filenameBelongsToList(filename)) {
- if (StringUtils.endsWithIgnoreCase(filename, GPXImporter.ZIP_FILE_EXTENSION)) {
- for (IConnector connector : ConnectorFactory.getConnectors()) {
- if (connector.isZippedGPXFile(filename)) {
- return true;
- }
- }
- return false;
- }
- // filter out waypoint files
- return !StringUtils.containsIgnoreCase(filename, GPXImporter.WAYPOINTS_FILE_SUFFIX);
- }
- return false;
- }
-
- public int getListId() {
- return listId;
- }
-
-}
+package cgeo.geocaching;
+
+import cgeo.geocaching.connector.ConnectorFactory;
+import cgeo.geocaching.connector.IConnector;
+import cgeo.geocaching.files.AbstractFileListActivity;
+import cgeo.geocaching.files.GPXImporter;
+import cgeo.geocaching.list.StoredList;
+import cgeo.geocaching.settings.Settings;
+import cgeo.geocaching.ui.GPXListAdapter;
+
+import org.apache.commons.lang3.StringUtils;
+
+import android.app.Activity;
+import android.content.Intent;
+
+import java.io.File;
+import java.util.Collections;
+import java.util.List;
+
+public class GpxFileListActivity extends AbstractFileListActivity<GPXListAdapter> {
+
+ public GpxFileListActivity() {
+ super(new String[] { "gpx", "loc", "zip" });
+ }
+
+ @Override
+ protected GPXListAdapter getAdapter(List<File> files) {
+ return new GPXListAdapter(this, files);
+ }
+
+ @Override
+ protected List<File> getBaseFolders() {
+ return Collections.singletonList(new File(Settings.getGpxImportDir()));
+ }
+
+ public static void startSubActivity(Activity fromActivity, int listId) {
+ final Intent intent = new Intent(fromActivity, GpxFileListActivity.class);
+ intent.putExtra(Intents.EXTRA_LIST_ID, StoredList.getConcreteList(listId));
+ fromActivity.startActivityForResult(intent, 0);
+ }
+
+ @Override
+ protected boolean filenameBelongsToList(final String filename) {
+ if (super.filenameBelongsToList(filename)) {
+ if (StringUtils.endsWithIgnoreCase(filename, GPXImporter.ZIP_FILE_EXTENSION)) {
+ for (IConnector connector : ConnectorFactory.getConnectors()) {
+ if (connector.isZippedGPXFile(filename)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ // filter out waypoint files
+ return !StringUtils.containsIgnoreCase(filename, GPXImporter.WAYPOINTS_FILE_SUFFIX);
+ }
+ return false;
+ }
+
+ public int getListId() {
+ return listId;
+ }
+
+}
diff --git a/main/src/cgeo/geocaching/MainActivity.java b/main/src/cgeo/geocaching/MainActivity.java
index 2d6e9f0..de3968f 100644
--- a/main/src/cgeo/geocaching/MainActivity.java
+++ b/main/src/cgeo/geocaching/MainActivity.java
@@ -6,8 +6,6 @@ import butterknife.InjectView;
import cgeo.geocaching.activity.AbstractActionBarActivity;
import cgeo.geocaching.connector.ConnectorFactory;
import cgeo.geocaching.connector.capability.ILogin;
-import cgeo.geocaching.connector.gc.GCConnector;
-import cgeo.geocaching.connector.gc.GCLogin;
import cgeo.geocaching.enumerations.CacheType;
import cgeo.geocaching.enumerations.StatusCode;
import cgeo.geocaching.geopoint.Geopoint;
@@ -16,6 +14,8 @@ import cgeo.geocaching.list.PseudoList;
import cgeo.geocaching.list.StoredList;
import cgeo.geocaching.maps.CGeoMap;
import cgeo.geocaching.sensors.GeoDirHandler;
+import cgeo.geocaching.sensors.GpsStatusProvider;
+import cgeo.geocaching.sensors.GpsStatusProvider.Status;
import cgeo.geocaching.sensors.IGeoData;
import cgeo.geocaching.settings.Settings;
import cgeo.geocaching.settings.SettingsActivity;
@@ -36,8 +36,8 @@ import rx.Observable;
import rx.Observable.OnSubscribe;
import rx.Subscriber;
import rx.android.observables.AndroidObservable;
+import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
-import rx.subscriptions.Subscriptions;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
@@ -145,37 +145,16 @@ public class MainActivity extends AbstractActionBarActivity {
return StringUtils.join(addressParts, ", ");
}
- private class SatellitesHandler extends GeoDirHandler {
-
- private boolean gpsEnabled = false;
- private int satellitesFixed = 0;
- private int satellitesVisible = 0;
-
+ private final Action1<GpsStatusProvider.Status> satellitesHandler = new Action1<Status>() {
@Override
- public void updateGeoData(final IGeoData data) {
- if (data.getGpsEnabled() == gpsEnabled &&
- data.getSatellitesFixed() == satellitesFixed &&
- data.getSatellitesVisible() == satellitesVisible) {
- return;
- }
- gpsEnabled = data.getGpsEnabled();
- satellitesFixed = data.getSatellitesFixed();
- satellitesVisible = data.getSatellitesVisible();
-
- if (gpsEnabled) {
- if (satellitesFixed > 0) {
- navSatellites.setText(res.getString(R.string.loc_sat) + ": " + satellitesFixed + '/' + satellitesVisible);
- } else if (satellitesVisible >= 0) {
- navSatellites.setText(res.getString(R.string.loc_sat) + ": 0/" + satellitesVisible);
- }
+ public void call(final Status gpsStatus) {
+ if (gpsStatus.gpsEnabled) {
+ navSatellites.setText(res.getString(R.string.loc_sat) + ": " + gpsStatus.satellitesFixed + '/' + gpsStatus.satellitesVisible);
} else {
navSatellites.setText(res.getString(R.string.loc_gps_disabled));
}
}
-
- }
-
- private final SatellitesHandler satellitesHandler = new SatellitesHandler();
+ };
private final Handler firstLoginHandler = new Handler() {
@@ -229,7 +208,8 @@ public class MainActivity extends AbstractActionBarActivity {
@Override
public void onResume() {
- super.onResume(Subscriptions.from(locationUpdater.start(GeoDirHandler.UPDATE_GEODATA), satellitesHandler.start(GeoDirHandler.UPDATE_GEODATA)));
+ super.onResume(locationUpdater.start(GeoDirHandler.UPDATE_GEODATA),
+ app.gpsStatusObservable().observeOn(AndroidSchedulers.mainThread()).subscribe(satellitesHandler));
updateUserInfoHandler.sendEmptyMessage(-1);
startBackgroundLogin();
init();
@@ -245,9 +225,9 @@ public class MainActivity extends AbstractActionBarActivity {
new Thread() {
@Override
public void run() {
- if (mustLogin && conn == GCConnector.getInstance()) {
+ if (mustLogin) {
// Properly log out from geocaching.com
- GCLogin.getInstance().logout();
+ conn.logout();
}
conn.login(firstLoginHandler, MainActivity.this);
updateUserInfoHandler.sendEmptyMessage(-1);
diff --git a/main/src/cgeo/geocaching/SelectMapfileActivity.java b/main/src/cgeo/geocaching/SelectMapfileActivity.java
index dc898d7..da41250 100644
--- a/main/src/cgeo/geocaching/SelectMapfileActivity.java
+++ b/main/src/cgeo/geocaching/SelectMapfileActivity.java
@@ -33,7 +33,7 @@ public class SelectMapfileActivity extends AbstractFileListActivity<FileSelectio
private String mapFile;
- private static int REQUEST_DIRECTORY = 1;
+ private final static int REQUEST_DIRECTORY = 1;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -98,8 +98,8 @@ public class SelectMapfileActivity extends AbstractFileListActivity<FileSelectio
}
@Override
- public void setCurrentFile(String newFile) {
- mapFile = newFile;
+ public void setCurrentFile(String name) {
+ mapFile = name;
}
@Override
diff --git a/main/src/cgeo/geocaching/activity/AbstractActivity.java b/main/src/cgeo/geocaching/activity/AbstractActivity.java
index e3df1f7..a28fcfa 100644
--- a/main/src/cgeo/geocaching/activity/AbstractActivity.java
+++ b/main/src/cgeo/geocaching/activity/AbstractActivity.java
@@ -86,9 +86,9 @@ public abstract class AbstractActivity extends ActionBarActivity implements IAbs
return super.onOptionsItemSelected(item);
}
- public void onResume(final Subscription resumeSubscription) {
+ public void onResume(final Subscription... resumeSubscriptions) {
super.onResume();
- this.resumeSubscription = resumeSubscription;
+ this.resumeSubscription = Subscriptions.from(resumeSubscriptions);
}
@Override
diff --git a/main/src/cgeo/geocaching/apps/cache/navi/PebbleApp.java b/main/src/cgeo/geocaching/apps/cache/navi/PebbleApp.java
index ac83085..5012195 100644
--- a/main/src/cgeo/geocaching/apps/cache/navi/PebbleApp.java
+++ b/main/src/cgeo/geocaching/apps/cache/navi/PebbleApp.java
@@ -1,26 +1,26 @@
-package cgeo.geocaching.apps.cache.navi;
-
-import cgeo.geocaching.R;
-import cgeo.geocaching.geopoint.Geopoint;
-
-import android.content.Intent;
-
-/**
- * Application for communication with the Pebble watch.
- *
- */
-class PebbleApp extends AbstractRadarApp {
-
- private static final String INTENT = "com.webmajstr.pebble_gc.NAVIGATE_TO";
- private static final String PACKAGE_NAME = "com.webmajstr.pebble_gc";
-
- PebbleApp() {
- super(getString(R.string.cache_menu_pebble), R.id.cache_app_pebble, INTENT, PACKAGE_NAME);
- }
-
- @Override
- protected void addCoordinates(final Intent intent, final Geopoint coords) {
- intent.putExtra("latitude", coords.getLatitude());
- intent.putExtra("longitude", coords.getLongitude());
- }
+package cgeo.geocaching.apps.cache.navi;
+
+import cgeo.geocaching.R;
+import cgeo.geocaching.geopoint.Geopoint;
+
+import android.content.Intent;
+
+/**
+ * Application for communication with the Pebble watch.
+ *
+ */
+class PebbleApp extends AbstractRadarApp {
+
+ private static final String INTENT = "com.webmajstr.pebble_gc.NAVIGATE_TO";
+ private static final String PACKAGE_NAME = "com.webmajstr.pebble_gc";
+
+ PebbleApp() {
+ super(getString(R.string.cache_menu_pebble), R.id.cache_app_pebble, INTENT, PACKAGE_NAME);
+ }
+
+ @Override
+ protected void addCoordinates(final Intent intent, final Geopoint coords) {
+ intent.putExtra("latitude", coords.getLatitude());
+ intent.putExtra("longitude", coords.getLongitude());
+ }
} \ No newline at end of file
diff --git a/main/src/cgeo/geocaching/concurrent/BlockingThreadPool.java b/main/src/cgeo/geocaching/concurrent/BlockingThreadPool.java
deleted file mode 100644
index a6d7e9b..0000000
--- a/main/src/cgeo/geocaching/concurrent/BlockingThreadPool.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package cgeo.geocaching.concurrent;
-
-
-import java.util.concurrent.ArrayBlockingQueue;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-
-/**
- * BlockingThreadPool restricts the amount of parallel threads executing Runnables.
- */
-public class BlockingThreadPool {
- /** The queue holding the Runnable. **/
- private BlockingQueue<Runnable> queue = null;
- /** The Executor. **/
- private ThreadPoolExecutor executor;
-
- /**
- * Creates a ThreadPool with a given maximum of parallel threads running.
- * Idle threads will be stopped until new threads are added.
- *
- * @param poolSize
- * Maximum amout of parallel Threads
- * @param priority
- * The Thread priority e.g. Thread.MIN_PRIORITY
- */
- public BlockingThreadPool(int poolSize, int priority) {
- ThreadFactory threadFactory = new PriorityThreadFactory(priority);
- this.queue = new ArrayBlockingQueue<>(poolSize, true);
- this.executor = new ThreadPoolExecutor(0, poolSize, 5, TimeUnit.SECONDS, this.queue);
- this.executor.setThreadFactory(threadFactory);
- }
-
- /**
- * Add a runnable to the pool. This will start the core threads in the underlying
- * executor and try to add the Runnable to the pool. This method waits until timeout
- * if no free thread is available.
- *
- * @param task
- * The Runnable to add to the pool
- * @param timeout
- * The timeout to wait for a free thread
- * @param unit
- * The timeout unit
- * @return true/false successful added
- * @throws InterruptedException
- * Operation was interrupted
- */
- public boolean add(Runnable task, int timeout, TimeUnit unit) throws InterruptedException {
- this.executor.setCorePoolSize(this.executor.getMaximumPoolSize());
- this.executor.prestartAllCoreThreads();
- boolean successfull = this.queue.offer(task, timeout, unit);
- this.executor.setCorePoolSize(0);
- return successfull;
- }
-}
diff --git a/main/src/cgeo/geocaching/concurrent/PriorityThreadFactory.java b/main/src/cgeo/geocaching/concurrent/PriorityThreadFactory.java
deleted file mode 100644
index 0da198b..0000000
--- a/main/src/cgeo/geocaching/concurrent/PriorityThreadFactory.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package cgeo.geocaching.concurrent;
-
-import org.eclipse.jdt.annotation.NonNull;
-
-import java.util.concurrent.ThreadFactory;
-
-/**
- * Helper class for setting Thread priority in ThreadPool.
- */
-public class PriorityThreadFactory implements ThreadFactory {
- private int priority;
-
- public PriorityThreadFactory(int priority) {
- this.priority = priority;
- }
-
- @NonNull
- @Override
- public Thread newThread(Runnable r) {
- Thread result = new Thread(r);
- result.setPriority(this.priority);
- return result;
- }
-
-}
diff --git a/main/src/cgeo/geocaching/connector/AbstractConnector.java b/main/src/cgeo/geocaching/connector/AbstractConnector.java
index 7e1ca13..8138e96 100644
--- a/main/src/cgeo/geocaching/connector/AbstractConnector.java
+++ b/main/src/cgeo/geocaching/connector/AbstractConnector.java
@@ -105,9 +105,9 @@ public abstract class AbstractConnector implements IConnector {
return null;
}
- protected static boolean isNumericId(final String string) {
+ protected static boolean isNumericId(final String str) {
try {
- return Integer.parseInt(string) > 0;
+ return Integer.parseInt(str) > 0;
} catch (NumberFormatException e) {
}
return false;
@@ -295,4 +295,6 @@ public abstract class AbstractConnector implements IConnector {
return actions;
}
+ public void logout() {
+ }
}
diff --git a/main/src/cgeo/geocaching/connector/capability/ILogin.java b/main/src/cgeo/geocaching/connector/capability/ILogin.java
index 4a839c8..b8b4975 100644
--- a/main/src/cgeo/geocaching/connector/capability/ILogin.java
+++ b/main/src/cgeo/geocaching/connector/capability/ILogin.java
@@ -23,6 +23,11 @@ public interface ILogin extends IConnector {
boolean login(Handler handler, Context fromActivity);
/**
+ * Log out of the connector if possible.
+ */
+ void logout();
+
+ /**
* Returns the status of the last {@link}login() request
*
* @return
diff --git a/main/src/cgeo/geocaching/connector/ec/ECApi.java b/main/src/cgeo/geocaching/connector/ec/ECApi.java
index 421d112..ae266fa 100644
--- a/main/src/cgeo/geocaching/connector/ec/ECApi.java
+++ b/main/src/cgeo/geocaching/connector/ec/ECApi.java
@@ -14,22 +14,24 @@ import cgeo.geocaching.geopoint.Viewport;
import cgeo.geocaching.list.StoredList;
import cgeo.geocaching.network.Network;
import cgeo.geocaching.network.Parameters;
+import cgeo.geocaching.utils.JsonUtils;
import cgeo.geocaching.utils.Log;
import cgeo.geocaching.utils.SynchronizedDateFormat;
import ch.boye.httpclientandroidlib.HttpResponse;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-import java.util.ArrayList;
+import java.io.IOException;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
+import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
@@ -161,7 +163,7 @@ public class ECApi {
}
try {
- return new GPX10Parser(StoredList.TEMPORARY_LIST_ID).parse(response.getEntity().getContent(), null);
+ return new GPX10Parser(StoredList.TEMPORARY_LIST.id).parse(response.getEntity().getContent(), null);
} catch (Exception e) {
Log.e("Error importing gpx from extremcaching.com", e);
return Collections.emptyList();
@@ -175,42 +177,41 @@ public class ECApi {
if (StringUtils.isBlank(data) || StringUtils.equals(data, "[]")) {
return Collections.emptyList();
}
- final JSONArray json = new JSONArray(data);
- final int len = json.length();
- final List<Geocache> caches = new ArrayList<>(len);
- for (int i = 0; i < len; i++) {
- final Geocache cache = parseCache(json.getJSONObject(i));
+ final ArrayNode json = (ArrayNode) JsonUtils.reader.readTree(data);
+ final List<Geocache> caches = new LinkedList<>();
+ for (final JsonNode node: json) {
+ final Geocache cache = parseCache(node);
if (cache != null) {
caches.add(cache);
}
}
return caches;
- } catch (final JSONException e) {
- Log.w("JSONResult", e);
+ } catch (IOException | ClassCastException e) {
+ Log.w("importCachesFromJSON", e);
}
}
return Collections.emptyList();
}
- private static Geocache parseCache(final JSONObject response) {
- final Geocache cache = new Geocache();
- cache.setReliableLatLon(true);
+ private static Geocache parseCache(final JsonNode response) {
try {
- cache.setGeocode("EC" + response.getString("cache_id"));
- cache.setName(response.getString("title"));
- cache.setCoords(new Geopoint(response.getString("lat"), response.getString("lon")));
- cache.setType(getCacheType(response.getString("type")));
- cache.setDifficulty((float) response.getDouble("difficulty"));
- cache.setTerrain((float) response.getDouble("terrain"));
- cache.setSize(CacheSize.getById(response.getString("size")));
- cache.setFound(response.getInt("found") == 1);
+ final Geocache cache = new Geocache();
+ cache.setReliableLatLon(true);
+ cache.setGeocode("EC" + response.get("cache_id").asText());
+ cache.setName(response.get("title").asText());
+ cache.setCoords(new Geopoint(response.get("lat").asText(), response.get("lon").asText()));
+ cache.setType(getCacheType(response.get("type").asText()));
+ cache.setDifficulty((float) response.get("difficulty").asDouble());
+ cache.setTerrain((float) response.get("terrain").asDouble());
+ cache.setSize(CacheSize.getById(response.get("size").asText()));
+ cache.setFound(response.get("found").asInt() == 1);
DataStore.saveCache(cache, EnumSet.of(SaveFlag.CACHE));
- } catch (final JSONException e) {
+ return cache;
+ } catch (final NullPointerException e) {
Log.e("ECApi.parseCache", e);
return null;
}
- return cache;
}
private static CacheType getCacheType(final String cacheType) {
diff --git a/main/src/cgeo/geocaching/connector/ec/ECLogin.java b/main/src/cgeo/geocaching/connector/ec/ECLogin.java
index 012bdc9..35c2db4 100644
--- a/main/src/cgeo/geocaching/connector/ec/ECLogin.java
+++ b/main/src/cgeo/geocaching/connector/ec/ECLogin.java
@@ -7,14 +7,18 @@ import cgeo.geocaching.enumerations.StatusCode;
import cgeo.geocaching.network.Network;
import cgeo.geocaching.network.Parameters;
import cgeo.geocaching.settings.Settings;
+import cgeo.geocaching.utils.JsonUtils;
import cgeo.geocaching.utils.Log;
import ch.boye.httpclientandroidlib.HttpResponse;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.eclipse.jdt.annotation.Nullable;
-import org.json.JSONException;
-import org.json.JSONObject;
+
+import java.io.IOException;
public class ECLogin extends AbstractLogin {
@@ -26,7 +30,7 @@ public class ECLogin extends AbstractLogin {
}
private static class SingletonHolder {
- private static ECLogin INSTANCE = new ECLogin();
+ private final static ECLogin INSTANCE = new ECLogin();
}
public static ECLogin getInstance() {
@@ -93,18 +97,18 @@ public class ECLogin extends AbstractLogin {
setActualStatus(app.getString(R.string.init_login_popup_ok));
try {
- final JSONObject json = new JSONObject(data);
+ final JsonNode json = JsonUtils.reader.readTree(data);
- final String sid = json.getString("sid");
+ final String sid = json.get("sid").asText();
if (!StringUtils.isBlank(sid)) {
sessionId = sid;
setActualLoginStatus(true);
- setActualUserName(json.getString("username"));
- setActualCachesFound(json.getInt("found"));
+ setActualUserName(json.get("username").asText());
+ setActualCachesFound(json.get("found").asInt());
return true;
}
resetLoginStatus();
- } catch (final JSONException e) {
+ } catch (IOException | NullPointerException e) {
Log.e("ECLogin.getLoginStatus", e);
}
diff --git a/main/src/cgeo/geocaching/connector/gc/GCConnector.java b/main/src/cgeo/geocaching/connector/gc/GCConnector.java
index 294e969..ad00718 100644
--- a/main/src/cgeo/geocaching/connector/gc/GCConnector.java
+++ b/main/src/cgeo/geocaching/connector/gc/GCConnector.java
@@ -342,6 +342,11 @@ public class GCConnector extends AbstractConnector implements ISearchByGeocode,
}
@Override
+ public void logout() {
+ GCLogin.getInstance().logout();
+ }
+
+ @Override
public String getUserName() {
return GCLogin.getInstance().getActualUserName();
}
diff --git a/main/src/cgeo/geocaching/connector/gc/GCConstants.java b/main/src/cgeo/geocaching/connector/gc/GCConstants.java
index 7cf43dc..fe47a91 100644
--- a/main/src/cgeo/geocaching/connector/gc/GCConstants.java
+++ b/main/src/cgeo/geocaching/connector/gc/GCConstants.java
@@ -45,7 +45,6 @@ public final class GCConstants {
public final static Pattern PATTERN_OWNER_USERID = Pattern.compile("other caches <a href=\"/seek/nearest\\.aspx\\?u=(.*?)\">hidden</a> or");
public final static Pattern PATTERN_FOUND = Pattern.compile("ctl00_ContentBody_GeoNav_logText\">(Found It|Attended)");
public final static Pattern PATTERN_FOUND_ALTERNATIVE = Pattern.compile("<div class=\"StatusInformationWidget FavoriteWidget\"");
- public final static Pattern PATTERN_FOUND_DATE = Pattern.compile(">Logged on: ([^<]+?)<");
public final static Pattern PATTERN_OWNER_DISPLAYNAME = Pattern.compile("<div id=\"ctl00_ContentBody_mcd1\">[^<]+<a href=\"[^\"]+\">([^<]+)</a>");
public final static Pattern PATTERN_TYPE = Pattern.compile("<a href=\"/seek/nearest.aspx\\?tx=([0-9a-f-]+)");
public final static Pattern PATTERN_HIDDEN = Pattern.compile("<div id=\"ctl00_ContentBody_mcd2\">\\W*Hidden[\\s:]*([^<]+?)</div>");
diff --git a/main/src/cgeo/geocaching/connector/gc/GCLogin.java b/main/src/cgeo/geocaching/connector/gc/GCLogin.java
index e84851e..e99cdf6 100644
--- a/main/src/cgeo/geocaching/connector/gc/GCLogin.java
+++ b/main/src/cgeo/geocaching/connector/gc/GCLogin.java
@@ -177,6 +177,9 @@ public class GCLogin extends AbstractLogin {
return StatusCode.NO_ERROR;
}
+ private static String removeDotAndComma(final String str) {
+ return StringUtils.replaceChars(str, ".,", null);
+ }
/**
* Check if the user has been logged in when he retrieved the data.
@@ -203,7 +206,7 @@ public class GCLogin extends AbstractLogin {
setActualUserName(TextUtils.getMatch(page, GCConstants.PATTERN_LOGIN_NAME, true, "???"));
int cachesCount = 0;
try {
- cachesCount = Integer.parseInt(TextUtils.getMatch(page, GCConstants.PATTERN_CACHES_FOUND, true, "0").replaceAll("[,.]", ""));
+ cachesCount = Integer.parseInt(removeDotAndComma(TextUtils.getMatch(page, GCConstants.PATTERN_CACHES_FOUND, true, "0")));
} catch (final NumberFormatException e) {
Log.e("getLoginStatus: bad cache count", e);
}
@@ -268,7 +271,7 @@ public class GCLogin extends AbstractLogin {
Settings.setGCMemberStatus(GCConstants.MEMBER_STATUS_PM);
}
- setActualCachesFound(Integer.parseInt(TextUtils.getMatch(profile, GCConstants.PATTERN_CACHES_FOUND, true, "-1").replaceAll("[,.]", "")));
+ setActualCachesFound(Integer.parseInt(removeDotAndComma(TextUtils.getMatch(profile, GCConstants.PATTERN_CACHES_FOUND, true, "-1"))));
final String avatarURL = TextUtils.getMatch(profile, GCConstants.PATTERN_AVATAR_IMAGE_PROFILE_PAGE, false, null);
if (null != avatarURL) {
diff --git a/main/src/cgeo/geocaching/connector/gc/GCMap.java b/main/src/cgeo/geocaching/connector/gc/GCMap.java
index 27ce06e..bacaddb 100644
--- a/main/src/cgeo/geocaching/connector/gc/GCMap.java
+++ b/main/src/cgeo/geocaching/connector/gc/GCMap.java
@@ -9,6 +9,7 @@ import cgeo.geocaching.enumerations.CacheType;
import cgeo.geocaching.enumerations.LiveMapStrategy.Strategy;
import cgeo.geocaching.enumerations.LiveMapStrategy.StrategyFlag;
import cgeo.geocaching.enumerations.StatusCode;
+import cgeo.geocaching.files.ParserException;
import cgeo.geocaching.geopoint.Geopoint;
import cgeo.geocaching.geopoint.GeopointFormatter.Format;
import cgeo.geocaching.geopoint.Units;
@@ -16,20 +17,23 @@ import cgeo.geocaching.geopoint.Viewport;
import cgeo.geocaching.network.Parameters;
import cgeo.geocaching.settings.Settings;
import cgeo.geocaching.utils.Formatter;
+import cgeo.geocaching.utils.JsonUtils;
import cgeo.geocaching.utils.LeastRecentlyUsedMap;
import cgeo.geocaching.utils.Log;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
import rx.Observable;
import rx.functions.Func2;
import android.graphics.Bitmap;
+import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
@@ -60,53 +64,41 @@ public class GCMap {
// {"name":"HP: Hannover - Sahlkamp","gc":"GC2Q97X","g":"a09149ca-00e0-4aa2-b332-db2b4dfb18d2","available":true,"archived":false,"subrOnly":false,"li":false,"fp":"0","difficulty":{"text":1.0,"value":"1"},"terrain":{"text":1.5,"value":"1_5"},"hidden":"5/29/2011","container":{"text":"Small","value":"small.gif"},"type":{"text":"Traditional Cache","value":2},"owner":{"text":"GeoM@n","value":"1deaa69e-6bcc-421d-95a1-7d32b468cb82"}}]
// }
- final JSONObject json = new JSONObject(data);
- final String status = json.getString("status");
+ final ObjectNode json = (ObjectNode) JsonUtils.reader.readTree(data);
+ final String status = json.path("status").asText();
if (StringUtils.isBlank(status)) {
-
- throw new JSONException("No status inside JSON");
+ throw new ParserException("No status inside JSON");
}
if ("success".compareTo(status) != 0) {
- throw new JSONException("Wrong status inside JSON");
+ throw new ParserException("Wrong status inside JSON");
}
- final JSONArray dataArray = json.getJSONArray("data");
+ final ArrayNode dataArray = (ArrayNode) json.get("data");
if (dataArray == null) {
- throw new JSONException("No data inside JSON");
+ throw new ParserException("No data inside JSON");
}
final ArrayList<Geocache> caches = new ArrayList<>();
- for (int j = 0; j < dataArray.length(); j++) {
+ for (final JsonNode dataObject: dataArray) {
final Geocache cache = new Geocache();
-
- JSONObject dataObject = dataArray.getJSONObject(j);
- cache.setName(dataObject.getString("name"));
- cache.setGeocode(dataObject.getString("gc"));
- cache.setGuid(dataObject.getString("g")); // 34c2e609-5246-4f91-9029-d6c02b0f2a82"
- cache.setDisabled(!dataObject.getBoolean("available"));
- cache.setArchived(dataObject.getBoolean("archived"));
- cache.setPremiumMembersOnly(dataObject.getBoolean("subrOnly"));
+ cache.setName(dataObject.path("name").asText());
+ cache.setGeocode(dataObject.path("gc").asText());
+ cache.setGuid(dataObject.path("g").asText()); // 34c2e609-5246-4f91-9029-d6c02b0f2a82"
+ cache.setDisabled(!dataObject.path("available").asBoolean());
+ cache.setArchived(dataObject.path("archived").asBoolean());
+ cache.setPremiumMembersOnly(dataObject.path("subrOnly").asBoolean());
// "li" seems to be "false" always
- cache.setFavoritePoints(Integer.parseInt(dataObject.getString("fp")));
- JSONObject difficultyObj = dataObject.getJSONObject("difficulty");
- cache.setDifficulty(Float.parseFloat(difficultyObj.getString("text"))); // 3.5
- JSONObject terrainObj = dataObject.getJSONObject("terrain");
- cache.setTerrain(Float.parseFloat(terrainObj.getString("text"))); // 1.5
- cache.setHidden(GCLogin.parseGcCustomDate(dataObject.getString("hidden"), "MM/dd/yyyy")); // 7/23/2001
- JSONObject containerObj = dataObject.getJSONObject("container");
- cache.setSize(CacheSize.getById(containerObj.getString("text"))); // Regular
- JSONObject typeObj = dataObject.getJSONObject("type");
- cache.setType(CacheType.getByPattern(typeObj.getString("text"))); // Traditional Cache
- JSONObject ownerObj = dataObject.getJSONObject("owner");
- cache.setOwnerDisplayName(ownerObj.getString("text"));
+ cache.setFavoritePoints(Integer.parseInt(dataObject.path("fp").asText()));
+ cache.setDifficulty(Float.parseFloat(dataObject.path("difficulty").path("text").asText())); // 3.5
+ cache.setTerrain(Float.parseFloat(dataObject.path("terrain").path("text").asText())); // 1.5
+ cache.setHidden(GCLogin.parseGcCustomDate(dataObject.path("hidden").asText(), "MM/dd/yyyy")); // 7/23/2001
+ cache.setSize(CacheSize.getById(dataObject.path("container").path("text").asText())); // Regular
+ cache.setType(CacheType.getByPattern(dataObject.path("type").path("text").asText())); // Traditional Cache
+ cache.setOwnerDisplayName(dataObject.path("owner").path("text").asText());
caches.add(cache);
}
result.addAndPutInCache(caches);
- } catch (JSONException e) {
- result.setError(StatusCode.UNKNOWN_ERROR);
- } catch (ParseException e) {
- result.setError(StatusCode.UNKNOWN_ERROR);
- } catch (NumberFormatException e) {
+ } catch (ParserException | ParseException | IOException | NumberFormatException ignore) {
result.setError(StatusCode.UNKNOWN_ERROR);
}
return result;
@@ -125,7 +117,7 @@ public class GCMap {
final LeastRecentlyUsedMap<String, String> nameCache = new LeastRecentlyUsedMap.LruCache<>(2000); // JSON id, cache name
if (StringUtils.isEmpty(data)) {
- throw new JSONException("No page given");
+ throw new ParserException("No page given");
}
// Example JSON information
@@ -134,34 +126,33 @@ public class GCMap {
// "data":{"55_55":[{"i":"gEaR","n":"Spiel & Sport"}],"55_54":[{"i":"gEaR","n":"Spiel & Sport"}],"17_25":[{"i":"Rkzt","n":"EDSSW: Rathaus "}],"55_53":[{"i":"gEaR","n":"Spiel & Sport"}],"17_27":[{"i":"Rkzt","n":"EDSSW: Rathaus "}],"17_26":[{"i":"Rkzt","n":"EDSSW: Rathaus "}],"57_53":[{"i":"gEaR","n":"Spiel & Sport"}],"57_55":[{"i":"gEaR","n":"Spiel & Sport"}],"3_62":[{"i":"gOWz","n":"Baumarktserie - Wer Wo Was -"}],"3_61":[{"i":"gOWz","n":"Baumarktserie - Wer Wo Was -"}],"57_54":[{"i":"gEaR","n":"Spiel & Sport"}],"3_60":[{"i":"gOWz","n":"Baumarktserie - Wer Wo Was -"}],"15_27":[{"i":"Rkzt","n":"EDSSW: Rathaus "}],"15_26":[{"i":"Rkzt","n":"EDSSW: Rathaus "}],"15_25":[{"i":"Rkzt","n":"EDSSW: Rathaus "}],"4_60":[{"i":"gOWz","n":"Baumarktserie - Wer Wo Was -"}],"4_61":[{"i":"gOWz","n":"Baumarktserie - Wer Wo Was -"}],"4_62":[{"i":"gOWz","n":"Baumarktserie - Wer Wo Was -"}],"16_25":[{"i":"Rkzt","n":"EDSSW: Rathaus "}],"16_26":[{"i":"Rkzt","n":"EDSSW: Rathaus "}],"16_27":[{"i":"Rkzt","n":"EDSSW: Rathaus "}],"2_62":[{"i":"gOWz","n":"Baumarktserie - Wer Wo Was -"}],"2_60":[{"i":"gOWz","n":"Baumarktserie - Wer Wo Was -"}],"2_61":[{"i":"gOWz","n":"Baumarktserie - Wer Wo Was -"}],"56_53":[{"i":"gEaR","n":"Spiel & Sport"}],"56_54":[{"i":"gEaR","n":"Spiel & Sport"}],"56_55":[{"i":"gEaR","n":"Spiel & Sport"}]}
// }
- final JSONObject json = new JSONObject(data);
+ final ObjectNode json = (ObjectNode) JsonUtils.reader.readTree(data);
- final JSONArray grid = json.getJSONArray("grid");
- if (grid == null || grid.length() != (UTFGrid.GRID_MAXY + 1)) {
- throw new JSONException("No grid inside JSON");
+ final ArrayNode grid = (ArrayNode) json.get("grid");
+ if (grid == null || grid.size() != (UTFGrid.GRID_MAXY + 1)) {
+ throw new ParserException("No grid inside JSON");
}
- final JSONArray keys = json.getJSONArray("keys");
+ final ArrayNode keys = (ArrayNode) json.get("keys");
if (keys == null) {
- throw new JSONException("No keys inside JSON");
+ throw new ParserException("No keys inside JSON");
}
- final JSONObject dataObject = json.getJSONObject("data");
+ final ObjectNode dataObject = (ObjectNode) json.get("data");
if (dataObject == null) {
- throw new JSONException("No data inside JSON");
+ throw new ParserException("No data inside JSON");
}
// iterate over the data and construct all caches in this tile
Map<String, List<UTFGridPosition>> positions = new HashMap<>(); // JSON id as key
Map<String, List<UTFGridPosition>> singlePositions = new HashMap<>(); // JSON id as key
- for (int i = 1; i < keys.length(); i++) { // index 0 is empty
- String key = keys.getString(i);
- if (StringUtils.isNotBlank(key)) {
+ for (final JsonNode rawKey: keys) {
+ final String key = rawKey.asText();
+ if (StringUtils.isNotBlank(key)) { // index 0 is empty
UTFGridPosition pos = UTFGridPosition.fromString(key);
- JSONArray dataForKey = dataObject.getJSONArray(key);
- for (int j = 0; j < dataForKey.length(); j++) {
- JSONObject cacheInfo = dataForKey.getJSONObject(j);
- String id = cacheInfo.getString("i");
- nameCache.put(id, cacheInfo.getString("n"));
+ final ArrayNode dataForKey = (ArrayNode) dataObject.get(key);
+ for (final JsonNode cacheInfo: dataForKey) {
+ final String id = cacheInfo.get("i").asText();
+ nameCache.put(id, cacheInfo.get("n").asText());
List<UTFGridPosition> listOfPositions = positions.get(id);
List<UTFGridPosition> singleListOfPositions = singlePositions.get(id);
@@ -174,7 +165,7 @@ public class GCMap {
}
listOfPositions.add(pos);
- if (dataForKey.length() == 1) {
+ if (dataForKey.size() == 1) {
singleListOfPositions.add(pos);
}
@@ -220,9 +211,7 @@ public class GCMap {
searchResult.addAndPutInCache(caches);
Log.d("Retrieved " + searchResult.getCount() + " caches for tile " + tile.toString());
- } catch (RuntimeException e) {
- Log.e("GCMap.parseMapJSON", e);
- } catch (JSONException e) {
+ } catch (RuntimeException | ParserException | IOException e) {
Log.e("GCMap.parseMapJSON", e);
}
diff --git a/main/src/cgeo/geocaching/connector/gc/GCParser.java b/main/src/cgeo/geocaching/connector/gc/GCParser.java
index 60d7856..2b3aa11 100644
--- a/main/src/cgeo/geocaching/connector/gc/GCParser.java
+++ b/main/src/cgeo/geocaching/connector/gc/GCParser.java
@@ -30,6 +30,7 @@ import cgeo.geocaching.network.Parameters;
import cgeo.geocaching.settings.Settings;
import cgeo.geocaching.ui.DirectionImage;
import cgeo.geocaching.utils.CancellableHandler;
+import cgeo.geocaching.utils.JsonUtils;
import cgeo.geocaching.utils.Log;
import cgeo.geocaching.utils.MatcherWrapper;
import cgeo.geocaching.utils.RxUtils;
@@ -38,15 +39,16 @@ import cgeo.geocaching.utils.TextUtils;
import ch.boye.httpclientandroidlib.HttpResponse;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
import rx.Observable;
import rx.Observable.OnSubscribe;
@@ -59,6 +61,7 @@ import android.net.Uri;
import android.text.Html;
import java.io.File;
+import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
@@ -125,12 +128,12 @@ public abstract class GCParser {
page = page.substring(startPos + 1, endPos - startPos + 1); // cut between <table> and </table>
- final String[] rows = page.split("<tr class=");
- final int rows_count = rows.length;
+ final String[] rows = StringUtils.splitByWholeSeparator(page, "<tr class=");
+ final int rowsCount = rows.length;
int excludedCaches = 0;
final ArrayList<Geocache> caches = new ArrayList<>();
- for (int z = 1; z < rows_count; z++) {
+ for (int z = 1; z < rowsCount; z++) {
final Geocache cache = new Geocache();
final String row = rows[z];
@@ -161,7 +164,7 @@ public abstract class GCParser {
}
} catch (final RuntimeException e) {
// failed to parse GUID and/or Disabled
- Log.w("GCParser.parseSearch: Failed to parse GUID and/or Disabled data");
+ Log.w("GCParser.parseSearch: Failed to parse GUID and/or Disabled data", e);
}
if (Settings.isExcludeDisabledCaches() && (cache.isDisabled() || cache.isArchived())) {
@@ -211,12 +214,12 @@ public abstract class GCParser {
final String dateHidden = TextUtils.getMatch(row, GCConstants.PATTERN_SEARCH_HIDDEN_DATE, false, 1, null, false);
if (StringUtils.isNotBlank(dateHidden)) {
try {
- Date date = GCLogin.parseGcCustomDate(dateHidden);
+ final Date date = GCLogin.parseGcCustomDate(dateHidden);
if (date != null) {
cache.setHidden(date);
}
- } catch (ParseException e) {
- Log.e("Error parsing event date from search");
+ } catch (final ParseException e) {
+ Log.e("Error parsing event date from search", e);
}
}
@@ -266,7 +269,7 @@ public abstract class GCParser {
cache.setFavoritePoints(Integer.parseInt(result));
}
} catch (final NumberFormatException e) {
- Log.w("GCParser.parseSearch: Failed to parse favorite count");
+ Log.w("GCParser.parseSearch: Failed to parse favorite count", e);
}
caches.add(cache);
@@ -280,7 +283,7 @@ public abstract class GCParser {
searchResult.setTotalCountGC(Integer.parseInt(result) - excludedCaches);
}
} catch (final NumberFormatException e) {
- Log.w("GCParser.parseSearch: Failed to parse cache count");
+ Log.w("GCParser.parseSearch: Failed to parse cache count", e);
}
String recaptchaText = null;
@@ -380,10 +383,12 @@ public abstract class GCParser {
* Parse cache from text and return either an error code or a cache object in a pair. Note that inline logs are
* not parsed nor saved, while the cache itself is.
*
- * @param pageIn the page text to parse
- * @param handler the handler to send the progress notifications to
- * @return a pair, with a {@link StatusCode} on the left, and a non-nulll cache objet on the right
- * iff the status code is {@link StatusCode.NO_ERROR}.
+ * @param pageIn
+ * the page text to parse
+ * @param handler
+ * the handler to send the progress notifications to
+ * @return a pair, with a {@link StatusCode} on the left, and a non-null cache object on the right
+ * iff the status code is {@link StatusCode.NO_ERROR}.
*/
static private ImmutablePair<StatusCode, Geocache> parseCacheFromText(final String pageIn, @Nullable final CancellableHandler handler) {
CancellableHandler.sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_details);
@@ -408,7 +413,7 @@ public abstract class GCParser {
// first handle the content with line breaks, then trim everything for easier matching and reduced memory consumption in parsed fields
String personalNoteWithLineBreaks = "";
- MatcherWrapper matcher = new MatcherWrapper(GCConstants.PATTERN_PERSONALNOTE, pageIn);
+ final MatcherWrapper matcher = new MatcherWrapper(GCConstants.PATTERN_PERSONALNOTE, pageIn);
if (matcher.find()) {
personalNoteWithLineBreaks = matcher.group(1).trim();
}
@@ -490,7 +495,7 @@ public abstract class GCParser {
}
} catch (final ParseException e) {
// failed to parse cache hidden date
- Log.w("GCParser.parseCache: Failed to parse cache hidden (event) date");
+ Log.w("GCParser.parseCache: Failed to parse cache hidden (event) date", e);
}
// favorite
@@ -579,7 +584,7 @@ public abstract class GCParser {
}
} catch (final RuntimeException e) {
// failed to parse cache attributes
- Log.w("GCParser.parseCache: Failed to parse cache attributes");
+ Log.w("GCParser.parseCache: Failed to parse cache attributes", e);
}
// cache spoilers
@@ -608,7 +613,7 @@ public abstract class GCParser {
}
} catch (final RuntimeException e) {
// failed to parse cache spoilers
- Log.w("GCParser.parseCache: Failed to parse cache spoilers");
+ Log.w("GCParser.parseCache: Failed to parse cache spoilers", e);
}
// cache inventory
@@ -642,7 +647,7 @@ public abstract class GCParser {
}
} catch (final RuntimeException e) {
// failed to parse cache inventory
- Log.w("GCParser.parseCache: Failed to parse cache inventory (2)");
+ Log.w("GCParser.parseCache: Failed to parse cache inventory (2)", e);
}
// cache logs counts
@@ -664,7 +669,7 @@ public abstract class GCParser {
}
} catch (final NumberFormatException e) {
// failed to parse logs
- Log.w("GCParser.parseCache: Failed to parse cache log count");
+ Log.w("GCParser.parseCache: Failed to parse cache log count", e);
}
// waypoints - reset collection
@@ -680,7 +685,7 @@ public abstract class GCParser {
cache.addOrChangeWaypoint(waypoint, false);
cache.setUserModifiedCoords(true);
}
- } catch (final Geopoint.GeopointException e) {
+ } catch (final Geopoint.GeopointException ignored) {
}
int wpBegin = page.indexOf("<table class=\"Table\" id=\"ctl00_ContentBody_Waypoints\">");
@@ -707,10 +712,10 @@ public abstract class GCParser {
wpList = wpList.substring(wpBegin + 7, wpEnd);
}
- final String[] wpItems = wpList.split("<tr");
+ final String[] wpItems = StringUtils.splitByWholeSeparator(wpList, "<tr");
for (int j = 1; j < wpItems.length; j++) {
- String[] wp = wpItems[j].split("<td");
+ String[] wp = StringUtils.splitByWholeSeparator(wpItems[j], "<td");
// waypoint name
// res is null during the unit tests
@@ -736,7 +741,7 @@ public abstract class GCParser {
j++;
if (wpItems.length > j) {
- wp = wpItems[j].split("<td");
+ wp = StringUtils.splitByWholeSeparator(wpItems[j], "<td");
}
// waypoint note
@@ -762,7 +767,7 @@ public abstract class GCParser {
return StringUtils.replaceChars(numberWithPunctuation, ".,", "");
}
- public static SearchResult searchByNextPage(final SearchResult search, boolean showCaptcha, RecaptchaReceiver recaptchaReceiver) {
+ public static SearchResult searchByNextPage(final SearchResult search, final boolean showCaptcha, final RecaptchaReceiver recaptchaReceiver) {
if (search == null) {
return null;
}
@@ -845,7 +850,7 @@ public abstract class GCParser {
* @return
*/
@Nullable
- private static SearchResult searchByAny(final CacheType cacheType, final boolean my, final boolean showCaptcha, final Parameters params, RecaptchaReceiver recaptchaReceiver) {
+ private static SearchResult searchByAny(final CacheType cacheType, final boolean my, final boolean showCaptcha, final Parameters params, final RecaptchaReceiver recaptchaReceiver) {
insertCacheType(params, cacheType);
final String uri = "http://www.geocaching.com/seek/nearest.aspx";
@@ -871,12 +876,12 @@ public abstract class GCParser {
return search;
}
- public static SearchResult searchByCoords(final @NonNull Geopoint coords, final CacheType cacheType, final boolean showCaptcha, RecaptchaReceiver recaptchaReceiver) {
+ public static SearchResult searchByCoords(final @NonNull Geopoint coords, final CacheType cacheType, final boolean showCaptcha, final RecaptchaReceiver recaptchaReceiver) {
final Parameters params = new Parameters("lat", Double.toString(coords.getLatitude()), "lng", Double.toString(coords.getLongitude()));
return searchByAny(cacheType, false, showCaptcha, params, recaptchaReceiver);
}
- public static SearchResult searchByKeyword(final @NonNull String keyword, final CacheType cacheType, final boolean showCaptcha, RecaptchaReceiver recaptchaReceiver) {
+ public static SearchResult searchByKeyword(final @NonNull String keyword, final CacheType cacheType, final boolean showCaptcha, final RecaptchaReceiver recaptchaReceiver) {
if (StringUtils.isBlank(keyword)) {
Log.e("GCParser.searchByKeyword: No keyword given");
return null;
@@ -894,7 +899,7 @@ public abstract class GCParser {
return false;
}
- public static SearchResult searchByUsername(final String userName, final CacheType cacheType, final boolean showCaptcha, RecaptchaReceiver recaptchaReceiver) {
+ public static SearchResult searchByUsername(final String userName, final CacheType cacheType, final boolean showCaptcha, final RecaptchaReceiver recaptchaReceiver) {
if (StringUtils.isBlank(userName)) {
Log.e("GCParser.searchByUsername: No user name given");
return null;
@@ -905,7 +910,7 @@ public abstract class GCParser {
return searchByAny(cacheType, isSearchForMyCaches(userName), showCaptcha, params, recaptchaReceiver);
}
- public static SearchResult searchByPocketQuery(final String pocketGuid, final CacheType cacheType, final boolean showCaptcha, RecaptchaReceiver recaptchaReceiver) {
+ public static SearchResult searchByPocketQuery(final String pocketGuid, final CacheType cacheType, final boolean showCaptcha, final RecaptchaReceiver recaptchaReceiver) {
if (StringUtils.isBlank(pocketGuid)) {
Log.e("GCParser.searchByPocket: No guid name given");
return null;
@@ -916,7 +921,7 @@ public abstract class GCParser {
return searchByAny(cacheType, false, showCaptcha, params, recaptchaReceiver);
}
- public static SearchResult searchByOwner(final String userName, final CacheType cacheType, final boolean showCaptcha, RecaptchaReceiver recaptchaReceiver) {
+ public static SearchResult searchByOwner(final String userName, final CacheType cacheType, final boolean showCaptcha, final RecaptchaReceiver recaptchaReceiver) {
if (StringUtils.isBlank(userName)) {
Log.e("GCParser.searchByOwner: No user name given");
return null;
@@ -926,32 +931,28 @@ public abstract class GCParser {
return searchByAny(cacheType, isSearchForMyCaches(userName), showCaptcha, params, recaptchaReceiver);
}
- public static SearchResult searchByAddress(final String address, final CacheType cacheType, final boolean showCaptcha, RecaptchaReceiver recaptchaReceiver) {
+ public static SearchResult searchByAddress(final String address, final CacheType cacheType, final boolean showCaptcha, final RecaptchaReceiver recaptchaReceiver) {
if (StringUtils.isBlank(address)) {
Log.e("GCParser.searchByAddress: No address given");
return null;
}
- try {
- final JSONObject response = Network.requestJSON("http://www.geocaching.com/api/geocode", new Parameters("q", address));
- if (response == null) {
- return null;
- }
- if (!StringUtils.equalsIgnoreCase(response.getString("status"), "success")) {
- return null;
- }
- if (!response.has("data")) {
- return null;
- }
- final JSONObject data = response.getJSONObject("data");
- if (data == null) {
- return null;
- }
- return searchByCoords(new Geopoint(data.getDouble("lat"), data.getDouble("lng")), cacheType, showCaptcha, recaptchaReceiver);
- } catch (final JSONException e) {
- Log.w("GCParser.searchByAddress", e);
+
+ final ObjectNode response = Network.requestJSON("http://www.geocaching.com/api/geocode", new Parameters("q", address));
+ if (response == null) {
+ return null;
}
- return null;
+ if (!StringUtils.equalsIgnoreCase(response.path("status").asText(), "success")) {
+ return null;
+ }
+
+ final JsonNode data = response.path("data");
+ final JsonNode latNode = data.get("lat");
+ final JsonNode lngNode = data.get("lng");
+ if (latNode == null || lngNode == null) {
+ return null;
+ }
+ return searchByCoords(new Geopoint(latNode.asDouble(), lngNode.asDouble()), cacheType, showCaptcha, recaptchaReceiver);
}
@Nullable
@@ -1001,13 +1002,13 @@ public abstract class GCParser {
return null;
}
- String subPage = StringUtils.substringAfter(page, "class=\"PocketQueryListTable");
+ final String subPage = StringUtils.substringAfter(page, "class=\"PocketQueryListTable");
if (StringUtils.isEmpty(subPage)) {
Log.e("GCParser.searchPocketQueryList: class \"PocketQueryListTable\" not found on page");
return Collections.emptyList();
}
- List<PocketQueryList> list = new ArrayList<>();
+ final List<PocketQueryList> list = new ArrayList<>();
final MatcherWrapper matcherPocket = new MatcherWrapper(GCConstants.PATTERN_LIST_PQ, subPage);
@@ -1015,7 +1016,7 @@ public abstract class GCParser {
int maxCaches;
try {
maxCaches = Integer.parseInt(matcherPocket.group(1));
- } catch (NumberFormatException e) {
+ } catch (final NumberFormatException e) {
maxCaches = 0;
Log.e("GCParser.searchPocketQueryList: Unable to parse max caches", e);
}
@@ -1029,7 +1030,7 @@ public abstract class GCParser {
Collections.sort(list, new Comparator<PocketQueryList>() {
@Override
- public int compare(PocketQueryList left, PocketQueryList right) {
+ public int compare(final PocketQueryList left, final PocketQueryList right) {
return String.CASE_INSENSITIVE_ORDER.compare(left.getName(), right.getName());
}
});
@@ -1483,7 +1484,7 @@ public abstract class GCParser {
}
} catch (final RuntimeException e) {
// failed to parse trackable owner name
- Log.w("GCParser.parseTrackable: Failed to parse trackable owner name");
+ Log.w("GCParser.parseTrackable: Failed to parse trackable owner name", e);
}
// trackable origin
@@ -1514,7 +1515,7 @@ public abstract class GCParser {
}
} catch (final RuntimeException e) {
// failed to parse trackable last known place
- Log.w("GCParser.parseTrackable: Failed to parse trackable last known place");
+ Log.w("GCParser.parseTrackable: Failed to parse trackable last known place", e);
}
// released date - can be missing on the page
@@ -1522,12 +1523,12 @@ public abstract class GCParser {
if (releaseString != null) {
try {
trackable.setReleased(dateTbIn1.parse(releaseString));
- } catch (ParseException e) {
+ } catch (final ParseException ignore) {
if (trackable.getReleased() == null) {
try {
trackable.setReleased(dateTbIn2.parse(releaseString));
- } catch (ParseException e1) {
- Log.e("Could not parse trackable release " + releaseString);
+ } catch (final ParseException e) {
+ Log.e("Could not parse trackable release " + releaseString, e);
}
}
}
@@ -1563,7 +1564,7 @@ public abstract class GCParser {
}
} catch (final RuntimeException e) {
// failed to parse trackable details & image
- Log.w("GCParser.parseTrackable: Failed to parse trackable details & image");
+ Log.w("GCParser.parseTrackable: Failed to parse trackable details & image", e);
}
if (StringUtils.isEmpty(trackable.getDetails()) && page.contains(GCConstants.ERROR_TB_NOT_ACTIVATED)) {
trackable.setDetails(CgeoApplication.getInstance().getString(R.string.trackable_not_activated));
@@ -1585,7 +1586,7 @@ public abstract class GCParser {
long date = 0;
try {
date = GCLogin.parseGcCustomDate(matcherLogs.group(2)).getTime();
- } catch (final ParseException e) {
+ } catch (final ParseException ignore) {
}
final LogEntry logDone = new LogEntry(
@@ -1630,7 +1631,7 @@ public abstract class GCParser {
return trackable;
}
- private static String convertLinks(String input) {
+ private static String convertLinks(final String input) {
if (input == null) {
return null;
}
@@ -1657,7 +1658,7 @@ public abstract class GCParser {
final String paramName;
- SpecialLogs(String paramName) {
+ SpecialLogs(final String paramName) {
this.paramName = paramName;
}
@@ -1702,7 +1703,7 @@ public abstract class GCParser {
Log.e("GCParser.loadLogsFromDetails: error " + statusCode + " when requesting log information");
return Observable.empty();
}
- String rawResponse = Network.getResponseData(response);
+ final String rawResponse = Network.getResponseData(response);
if (rawResponse == null) {
Log.e("GCParser.loadLogsFromDetails: unable to read whole response");
return Observable.empty();
@@ -1723,56 +1724,51 @@ public abstract class GCParser {
}
try {
- final JSONObject resp = new JSONObject(rawResponse);
- if (!resp.getString("status").equals("success")) {
- Log.e("GCParser.loadLogsFromDetails: status is " + resp.getString("status"));
+ final ObjectNode resp = (ObjectNode) JsonUtils.reader.readTree(rawResponse);
+ if (!resp.path("status").asText().equals("success")) {
+ Log.e("GCParser.loadLogsFromDetails: status is " + resp.path("status").asText("[absent]"));
subscriber.onCompleted();
return;
}
- final JSONArray data = resp.getJSONArray("data");
-
- for (int index = 0; index < data.length(); index++) {
- final JSONObject entry = data.getJSONObject(index);
-
+ final ArrayNode data = (ArrayNode) resp.get("data");
+ for (final JsonNode entry: data) {
// FIXME: use the "LogType" field instead of the "LogTypeImage" one.
- final String logIconNameExt = entry.optString("LogTypeImage", ".gif");
+ final String logIconNameExt = entry.path("LogTypeImage").asText(".gif");
final String logIconName = logIconNameExt.substring(0, logIconNameExt.length() - 4);
long date = 0;
try {
- date = GCLogin.parseGcCustomDate(entry.getString("Visited")).getTime();
- } catch (final ParseException e) {
- Log.e("GCParser.loadLogsFromDetails: failed to parse log date.");
+ date = GCLogin.parseGcCustomDate(entry.get("Visited").asText()).getTime();
+ } catch (ParseException | NullPointerException e) {
+ Log.e("GCParser.loadLogsFromDetails: failed to parse log date", e);
}
// TODO: we should update our log data structure to be able to record
// proper coordinates, and make them clickable. In the meantime, it is
// better to integrate those coordinates into the text rather than not
// display them at all.
- final String latLon = entry.getString("LatLonString");
- final String logText = (StringUtils.isEmpty(latLon) ? "" : (latLon + "<br/><br/>")) + TextUtils.removeControlCharacters(entry.getString("LogText"));
+ final String latLon = entry.path("LatLonString").asText();
+ final String logText = (StringUtils.isEmpty(latLon) ? "" : (latLon + "<br/><br/>")) + TextUtils.removeControlCharacters(entry.path("LogText").asText());
final LogEntry logDone = new LogEntry(
- TextUtils.removeControlCharacters(entry.getString("UserName")),
+ TextUtils.removeControlCharacters(entry.path("UserName").asText()),
date,
LogType.getByIconName(logIconName),
logText);
- logDone.found = entry.getInt("GeocacheFindCount");
+ logDone.found = entry.path("GeocacheFindCount").asInt();
logDone.friend = markAsFriendsLog;
- final JSONArray images = entry.getJSONArray("Images");
- for (int i = 0; i < images.length(); i++) {
- final JSONObject image = images.getJSONObject(i);
- final String url = "http://imgcdn.geocaching.com/cache/log/large/" + image.getString("FileName");
- final String title = TextUtils.removeControlCharacters(image.getString("Name"));
+ final ArrayNode images = (ArrayNode) entry.get("Images");
+ for (final JsonNode image: images) {
+ final String url = "http://imgcdn.geocaching.com/cache/log/large/" + image.path("FileName").asText();
+ final String title = TextUtils.removeControlCharacters(image.path("Name").asText());
final Image logImage = new Image(url, title);
logDone.addLogImage(logImage);
}
subscriber.onNext(logDone);
}
- } catch (final JSONException e) {
- // failed to parse logs
+ } catch (final IOException e) {
Log.w("GCParser.loadLogsFromDetails: Failed to parse cache logs", e);
}
subscriber.onCompleted();
@@ -1781,7 +1777,7 @@ public abstract class GCParser {
}
@NonNull
- public static List<LogType> parseTypes(String page) {
+ public static List<LogType> parseTypes(final String page) {
if (StringUtils.isEmpty(page)) {
return Collections.emptyList();
}
@@ -1934,75 +1930,62 @@ public abstract class GCParser {
}
}
- public static boolean uploadModifiedCoordinates(Geocache cache, Geopoint wpt) {
+ public static boolean uploadModifiedCoordinates(final Geocache cache, final Geopoint wpt) {
return editModifiedCoordinates(cache, wpt);
}
- public static boolean deleteModifiedCoordinates(Geocache cache) {
+ public static boolean deleteModifiedCoordinates(final Geocache cache) {
return editModifiedCoordinates(cache, null);
}
- public static boolean editModifiedCoordinates(Geocache cache, Geopoint wpt) {
+ public static boolean editModifiedCoordinates(final Geocache cache, final Geopoint wpt) {
final String userToken = getUserToken(cache);
if (StringUtils.isEmpty(userToken)) {
return false;
}
- try {
- JSONObject jo;
- if (wpt != null) {
- jo = new JSONObject().put("dto", (new JSONObject().put("ut", userToken)
- .put("data", new JSONObject()
- .put("lat", wpt.getLatitudeE6() / 1E6)
- .put("lng", wpt.getLongitudeE6() / 1E6))));
- } else {
- jo = new JSONObject().put("dto", (new JSONObject().put("ut", userToken)));
- }
-
- final String uriSuffix = wpt != null ? "SetUserCoordinate" : "ResetUserCoordinate";
+ final ObjectNode jo = new ObjectNode(JsonUtils.factory);
+ final ObjectNode dto = jo.putObject("dto").put("ut", userToken);
+ if (wpt != null) {
+ dto.putObject("data").put("lat", wpt.getLatitudeE6() / 1E6).put("lng", wpt.getLongitudeE6() / 1E6);
+ }
- final String uriPrefix = "http://www.geocaching.com/seek/cache_details.aspx/";
- final HttpResponse response = Network.postJsonRequest(uriPrefix + uriSuffix, jo);
- Log.i("Sending to " + uriPrefix + uriSuffix + " :" + jo.toString());
+ final String uriSuffix = wpt != null ? "SetUserCoordinate" : "ResetUserCoordinate";
- if (response != null && response.getStatusLine().getStatusCode() == 200) {
- Log.i("GCParser.editModifiedCoordinates - edited on GC.com");
- return true;
- }
+ final String uriPrefix = "http://www.geocaching.com/seek/cache_details.aspx/";
+ final HttpResponse response = Network.postJsonRequest(uriPrefix + uriSuffix, jo);
+ Log.i("Sending to " + uriPrefix + uriSuffix + " :" + jo.toString());
- } catch (final JSONException e) {
- Log.e("Unknown exception with json wrap code", e);
+ if (response != null && response.getStatusLine().getStatusCode() == 200) {
+ Log.i("GCParser.editModifiedCoordinates - edited on GC.com");
+ return true;
}
+
Log.e("GCParser.deleteModifiedCoordinates - cannot delete modified coords");
return false;
}
- public static boolean uploadPersonalNote(Geocache cache) {
+ public static boolean uploadPersonalNote(final Geocache cache) {
final String userToken = getUserToken(cache);
if (StringUtils.isEmpty(userToken)) {
return false;
}
- try {
- final JSONObject jo = new JSONObject()
- .put("dto", (new JSONObject()
- .put("et", cache.getPersonalNote())
- .put("ut", userToken)));
+ final ObjectNode jo = new ObjectNode(JsonUtils.factory).putObject("dto")
+ .put("et", cache.getPersonalNote())
+ .put("ut", userToken);
- final String uriSuffix = "SetUserCacheNote";
+ final String uriSuffix = "SetUserCacheNote";
- final String uriPrefix = "http://www.geocaching.com/seek/cache_details.aspx/";
- final HttpResponse response = Network.postJsonRequest(uriPrefix + uriSuffix, jo);
- Log.i("Sending to " + uriPrefix + uriSuffix + " :" + jo.toString());
+ final String uriPrefix = "http://www.geocaching.com/seek/cache_details.aspx/";
+ final HttpResponse response = Network.postJsonRequest(uriPrefix + uriSuffix, jo);
+ Log.i("Sending to " + uriPrefix + uriSuffix + " :" + jo.toString());
- if (response != null && response.getStatusLine().getStatusCode() == 200) {
- Log.i("GCParser.uploadPersonalNote - uploaded to GC.com");
- return true;
- }
-
- } catch (final JSONException e) {
- Log.e("Unknown exception with json wrap code", e);
+ if (response != null && response.getStatusLine().getStatusCode() == 200) {
+ Log.i("GCParser.uploadPersonalNote - uploaded to GC.com");
+ return true;
}
+
Log.e("GCParser.uploadPersonalNote - cannot upload personal note");
return false;
}
diff --git a/main/src/cgeo/geocaching/connector/gc/Tile.java b/main/src/cgeo/geocaching/connector/gc/Tile.java
index 18fe65c..ff13fe3 100644
--- a/main/src/cgeo/geocaching/connector/gc/Tile.java
+++ b/main/src/cgeo/geocaching/connector/gc/Tile.java
@@ -56,11 +56,11 @@ public class Tile {
private final int zoomLevel;
private final Viewport viewPort;
- public Tile(Geopoint origin, int zoomlevel) {
+ public Tile(final Geopoint origin, final int zoomlevel) {
this(calcX(origin, clippedZoomlevel(zoomlevel)), calcY(origin, clippedZoomlevel(zoomlevel)), clippedZoomlevel(zoomlevel));
}
- private Tile(int tileX, int tileY, int zoomlevel) {
+ private Tile(final int tileX, final int tileY, final int zoomlevel) {
this.zoomLevel = clippedZoomlevel(zoomlevel);
@@ -74,7 +74,7 @@ public class Tile {
return zoomLevel;
}
- private static int clippedZoomlevel(int zoomlevel) {
+ private static int clippedZoomlevel(final int zoomlevel) {
return Math.max(Math.min(zoomlevel, ZOOMLEVEL_MAX), ZOOMLEVEL_MIN);
}
@@ -95,7 +95,7 @@ public class Tile {
*/
private static int calcY(final Geopoint origin, final int zoomlevel) {
// Optimization from Bing
- double sinLatRad = Math.sin(Math.toRadians(origin.getLatitude()));
+ final double sinLatRad = Math.sin(Math.toRadians(origin.getLatitude()));
// The cut of the fractional part instead of rounding to the nearest integer is intentional and part of the algorithm
return (int) ((0.5 - Math.log((1 + sinLatRad) / (1 - sinLatRad)) / (4 * Math.PI)) * NUMBER_OF_TILES[zoomlevel]);
}
@@ -115,13 +115,13 @@ public class Tile {
* href="http://developers.cloudmade.com/projects/tiles/examples/convert-coordinates-to-tile-numbers">Cloudmade</a>
*/
@NonNull
- public Geopoint getCoord(UTFGridPosition pos) {
+ public Geopoint getCoord(final UTFGridPosition pos) {
- double pixX = tileX * TILE_SIZE + pos.x * 4;
- double pixY = tileY * TILE_SIZE + pos.y * 4;
+ final double pixX = tileX * TILE_SIZE + pos.x * 4;
+ final double pixY = tileY * TILE_SIZE + pos.y * 4;
- double lonDeg = ((360.0 * pixX) / NUMBER_OF_PIXELS[this.zoomLevel]) - 180.0;
- double latRad = Math.atan(Math.sinh(Math.PI * (1 - 2 * pixY / NUMBER_OF_PIXELS[this.zoomLevel])));
+ final double lonDeg = ((360.0 * pixX) / NUMBER_OF_PIXELS[this.zoomLevel]) - 180.0;
+ final double latRad = Math.atan(Math.sinh(Math.PI * (1 - 2 * pixY / NUMBER_OF_PIXELS[this.zoomLevel])));
return new Geopoint(Math.toDegrees(latRad), lonDeg);
}
@@ -153,8 +153,8 @@ public class Tile {
/ Math.log(2)
);
- Tile tileLeft = new Tile(left, zoom);
- Tile tileRight = new Tile(right, zoom);
+ final Tile tileLeft = new Tile(left, zoom);
+ final Tile tileRight = new Tile(right, zoom);
if (Math.abs(tileLeft.tileX - tileRight.tileX) < (numberOfTiles - 1)) {
zoom += 1;
@@ -190,8 +190,8 @@ public class Tile {
) / Math.log(2)
);
- Tile tileBottom = new Tile(bottom, zoom);
- Tile tileTop = new Tile(top, zoom);
+ final Tile tileBottom = new Tile(bottom, zoom);
+ final Tile tileTop = new Tile(top, zoom);
if (Math.abs(tileBottom.tileY - tileTop.tileY) > (numberOfTiles - 1)) {
zoom -= 1;
@@ -200,7 +200,7 @@ public class Tile {
return Math.min(zoom, ZOOMLEVEL_MAX);
}
- private static double tanGrad(double angleGrad) {
+ private static double tanGrad(final double angleGrad) {
return Math.tan(angleGrad / 180.0 * Math.PI);
}
@@ -211,12 +211,12 @@ public class Tile {
* @param x
* @return
*/
- private static double asinh(double x) {
+ private static double asinh(final double x) {
return Math.log(x + Math.sqrt(x * x + 1.0));
}
@Override
- public boolean equals(Object o) {
+ public boolean equals(final Object o) {
if (this == o) {
return true;
}
@@ -260,7 +260,7 @@ public class Tile {
public Bitmap call() {
try {
return response != null ? BitmapFactory.decodeStream(response.getEntity().getContent()) : null;
- } catch (IOException e) {
+ } catch (final IOException e) {
Log.e("Tile.requestMapTile() ", e);
return null;
}
@@ -298,20 +298,20 @@ public class Tile {
* @return
*/
protected static Set<Tile> getTilesForViewport(final Viewport viewport, final int tilesOnAxis, final int minZoom) {
- Set<Tile> tiles = new HashSet<>();
- int zoom = Math.max(
+ final Set<Tile> tiles = new HashSet<>();
+ final int zoom = Math.max(
Math.min(Tile.calcZoomLon(viewport.bottomLeft, viewport.topRight, tilesOnAxis),
Tile.calcZoomLat(viewport.bottomLeft, viewport.topRight, tilesOnAxis)),
minZoom);
- Tile tileBottomLeft = new Tile(viewport.bottomLeft, zoom);
- Tile tileTopRight = new Tile(viewport.topRight, zoom);
+ final Tile tileBottomLeft = new Tile(viewport.bottomLeft, zoom);
+ final Tile tileTopRight = new Tile(viewport.topRight, zoom);
- int xLow = Math.min(tileBottomLeft.getX(), tileTopRight.getX());
- int xHigh = Math.max(tileBottomLeft.getX(), tileTopRight.getX());
+ final int xLow = Math.min(tileBottomLeft.getX(), tileTopRight.getX());
+ final int xHigh = Math.max(tileBottomLeft.getX(), tileTopRight.getX());
- int yLow = Math.min(tileBottomLeft.getY(), tileTopRight.getY());
- int yHigh = Math.max(tileBottomLeft.getY(), tileTopRight.getY());
+ final int yLow = Math.min(tileBottomLeft.getY(), tileTopRight.getY());
+ final int yHigh = Math.max(tileBottomLeft.getY(), tileTopRight.getY());
for (int xNum = xLow; xNum <= xHigh; xNum++) {
for (int yNum = yLow; yNum <= yHigh; yNum++) {
@@ -324,8 +324,6 @@ public class Tile {
public static class TileCache extends LeastRecentlyUsedSet<Tile> {
- private static final long serialVersionUID = -1942301031192719547L;
-
public TileCache() {
super(64);
}
diff --git a/main/src/cgeo/geocaching/connector/oc/OCApiConnector.java b/main/src/cgeo/geocaching/connector/oc/OCApiConnector.java
index 284234e..9e9ec7f 100644
--- a/main/src/cgeo/geocaching/connector/oc/OCApiConnector.java
+++ b/main/src/cgeo/geocaching/connector/oc/OCApiConnector.java
@@ -31,7 +31,7 @@ public class OCApiConnector extends OCConnector implements ISearchByGeocode {
private final ApiSupport apiSupport;
private final String licenseString;
- public OCApiConnector(String name, String host, String prefix, String cK, String licenseString, ApiSupport apiSupport) {
+ public OCApiConnector(final String name, final String host, final String prefix, final String cK, final String licenseString, final ApiSupport apiSupport) {
super(name, host, prefix);
this.cK = cK;
this.apiSupport = apiSupport;
@@ -39,7 +39,12 @@ public class OCApiConnector extends OCConnector implements ISearchByGeocode {
}
public void addAuthentication(final Parameters params) {
- params.put(CryptUtils.rot13("pbafhzre_xrl"), CryptUtils.rot13(cK));
+ final String rotCK = CryptUtils.rot13(cK);
+ // check that developers are not using the Ant defined properties without any values
+ if (StringUtils.startsWith(rotCK, "${")) {
+ throw new IllegalStateException("invalid OKAPI OAuth token " + rotCK);
+ }
+ params.put(CryptUtils.rot13("pbafhzre_xrl"), rotCK);
}
@Override
@@ -93,13 +98,13 @@ public class OCApiConnector extends OCConnector implements ISearchByGeocode {
/**
* Checks if a search based on a user name targets the current user
- *
+ *
* @param username
* Name of the user the query is searching after
* @return True - search target and current is same, False - current user not known or not the same as username
*/
@SuppressWarnings("static-method")
- public boolean isSearchForMyCaches(String username) {
+ public boolean isSearchForMyCaches(final String username) {
return false;
}
}
diff --git a/main/src/cgeo/geocaching/connector/oc/OkapiClient.java b/main/src/cgeo/geocaching/connector/oc/OkapiClient.java
index 3df62aa..be347d2 100644
--- a/main/src/cgeo/geocaching/connector/oc/OkapiClient.java
+++ b/main/src/cgeo/geocaching/connector/oc/OkapiClient.java
@@ -27,23 +27,27 @@ import cgeo.geocaching.geopoint.GeopointFormatter;
import cgeo.geocaching.geopoint.Viewport;
import cgeo.geocaching.network.Network;
import cgeo.geocaching.network.OAuth;
+import cgeo.geocaching.network.OAuthTokens;
import cgeo.geocaching.network.Parameters;
import cgeo.geocaching.settings.Settings;
+import cgeo.geocaching.utils.JsonUtils;
import cgeo.geocaching.utils.Log;
import cgeo.geocaching.utils.SynchronizedDateFormat;
import ch.boye.httpclientandroidlib.HttpResponse;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.tuple.ImmutablePair;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
import android.net.Uri;
+import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
@@ -56,6 +60,7 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;
+import java.util.regex.Pattern;
final class OkapiClient {
@@ -131,6 +136,8 @@ final class OkapiClient {
private static final String METHOD_SEARCH_NEAREST = "services/caches/search/nearest";
private static final String METHOD_RETRIEVE_CACHES = "services/caches/geocaches";
+ private static final Pattern PATTERN_TIMEZONE = Pattern.compile("([+-][01][0-9]):([03])0");
+
public static Geocache getCache(final String geoCode) {
final Parameters params = new Parameters("cache_code", geoCode);
final IConnector connector = ConnectorFactory.getConnector(geoCode);
@@ -208,10 +215,15 @@ final class OkapiClient {
}
addFilterParams(valueMap, connector, my);
- params.add("search_params", new JSONObject(valueMap).toString());
+ try {
+ params.add("search_params", JsonUtils.writer.writeValueAsString(params));
+ } catch (final JsonProcessingException e) {
+ Log.e("requestCaches", e);
+ return Collections.emptyList();
+ }
addRetrieveParams(params, connector);
- final JSONObject data = request(connector, OkapiService.SERVICE_SEARCH_AND_RETRIEVE, params).data;
+ final ObjectNode data = request(connector, OkapiService.SERVICE_SEARCH_AND_RETRIEVE, params).data;
if (data == null) {
return Collections.emptyList();
@@ -244,7 +256,7 @@ final class OkapiClient {
final Parameters params = new Parameters("cache_code", cache.getGeocode());
params.add("watched", watched ? "true" : "false");
- final JSONObject data = request(connector, OkapiService.SERVICE_MARK_CACHE, params).data;
+ final ObjectNode data = request(connector, OkapiService.SERVICE_MARK_CACHE, params).data;
if (data == null) {
return false;
@@ -268,68 +280,62 @@ final class OkapiClient {
params.add("password", logPassword);
}
- final JSONObject data = request(connector, OkapiService.SERVICE_SUBMIT_LOG, params).data;
+ final ObjectNode data = request(connector, OkapiService.SERVICE_SUBMIT_LOG, params).data;
if (data == null) {
return new LogResult(StatusCode.LOG_POST_ERROR, "");
}
try {
- if (data.getBoolean("success")) {
- return new LogResult(StatusCode.NO_ERROR, data.getString("log_uuid"));
+ if (data.get("success").asBoolean()) {
+ return new LogResult(StatusCode.NO_ERROR, data.get("log_uuid").asText());
}
return new LogResult(StatusCode.LOG_POST_ERROR, "");
- } catch (final JSONException e) {
+ } catch (final NullPointerException e) {
Log.e("OkapiClient.postLog", e);
}
return new LogResult(StatusCode.LOG_POST_ERROR, "");
}
- private static List<Geocache> parseCaches(final JSONObject response) {
+ private static List<Geocache> parseCaches(final ObjectNode response) {
try {
// Check for empty result
- final String result = response.getString("results");
+ final String result = response.get("results").asText();
if (StringUtils.isBlank(result) || StringUtils.equals(result, "[]")) {
return Collections.emptyList();
}
// Get and iterate result list
- final JSONObject cachesResponse = response.getJSONObject("results");
+ final ObjectNode cachesResponse = (ObjectNode) response.get("results");
if (cachesResponse != null) {
- final List<Geocache> caches = new ArrayList<>(cachesResponse.length());
- final Iterator<?> keys = cachesResponse.keys();
- while (keys.hasNext()) {
- final Object next = keys.next();
- if (next instanceof String) {
- final String key = (String) next;
- final Geocache cache = parseSmallCache(cachesResponse.getJSONObject(key));
- caches.add(cache);
- }
+ final List<Geocache> caches = new ArrayList<>(cachesResponse.size());
+ final Iterator<JsonNode> it = cachesResponse.elements();
+ while (it.hasNext()) {
+ caches.add(parseSmallCache((ObjectNode) it.next()));
}
return caches;
}
- } catch (final JSONException e) {
+ } catch (ClassCastException | NullPointerException e) {
Log.e("OkapiClient.parseCachesResult", e);
}
return Collections.emptyList();
}
- private static Geocache parseSmallCache(final JSONObject response) {
+ private static Geocache parseSmallCache(final ObjectNode response) {
final Geocache cache = new Geocache();
cache.setReliableLatLon(true);
try {
-
parseCoreCache(response, cache);
-
DataStore.saveCache(cache, EnumSet.of(SaveFlag.CACHE));
- } catch (final JSONException e) {
+ } catch (final NullPointerException e) {
+ // FIXME: here we may return a partially filled cache
Log.e("OkapiClient.parseSmallCache", e);
}
return cache;
}
- private static Geocache parseCache(final JSONObject response) {
+ private static Geocache parseCache(final ObjectNode response) {
final Geocache cache = new Geocache();
cache.setReliableLatLon(true);
try {
@@ -337,28 +343,27 @@ final class OkapiClient {
parseCoreCache(response, cache);
// not used: url
- final JSONObject ownerObject = response.getJSONObject(CACHE_OWNER);
- final String owner = parseUser(ownerObject);
+ final String owner = parseUser(response.get(CACHE_OWNER));
cache.setOwnerDisplayName(owner);
// OpenCaching has no distinction between user id and user display name. Set the ID anyway to simplify c:geo workflows.
cache.setOwnerUserId(owner);
- cache.getLogCounts().put(LogType.FOUND_IT, response.getInt(CACHE_FOUNDS));
- cache.getLogCounts().put(LogType.DIDNT_FIND_IT, response.getInt(CACHE_NOTFOUNDS));
+ cache.getLogCounts().put(LogType.FOUND_IT, response.get(CACHE_FOUNDS).asInt());
+ cache.getLogCounts().put(LogType.DIDNT_FIND_IT, response.get(CACHE_NOTFOUNDS).asInt());
// only current Api
- cache.getLogCounts().put(LogType.WILL_ATTEND, response.optInt(CACHE_WILLATTENDS));
+ cache.getLogCounts().put(LogType.WILL_ATTEND, response.path(CACHE_WILLATTENDS).asInt());
- if (!response.isNull(CACHE_RATING)) {
- cache.setRating((float) response.getDouble(CACHE_RATING));
+ if (response.has(CACHE_RATING)) {
+ cache.setRating((float) response.get(CACHE_RATING).asDouble());
}
- cache.setVotes(response.getInt(CACHE_VOTES));
+ cache.setVotes(response.get(CACHE_VOTES).asInt());
- cache.setFavoritePoints(response.getInt(CACHE_RECOMMENDATIONS));
+ cache.setFavoritePoints(response.get(CACHE_RECOMMENDATIONS).asInt());
// not used: req_password
// Prepend gc-link to description if available
final StringBuilder description = new StringBuilder(500);
- if (!response.isNull("gc_code")) {
- final String gccode = response.getString("gc_code");
+ if (response.hasNonNull("gc_code")) {
+ final String gccode = response.get("gc_code").asText();
description.append(CgeoApplication.getInstance().getResources()
.getString(R.string.cache_listed_on, GCConnector.getInstance().getName()))
.append(": <a href=\"http://coord.info/")
@@ -367,71 +372,70 @@ final class OkapiClient {
.append(gccode)
.append("</a><br /><br />");
}
- description.append(response.getString(CACHE_DESCRIPTION));
+ description.append(response.get(CACHE_DESCRIPTION).asText());
cache.setDescription(description.toString());
// currently the hint is delivered as HTML (contrary to OKAPI documentation), so we can store it directly
- cache.setHint(response.getString(CACHE_HINT));
+ cache.setHint(response.get(CACHE_HINT).asText());
// not used: hints
- final JSONArray images = response.getJSONArray(CACHE_IMAGES);
+ final ArrayNode images = (ArrayNode) response.get(CACHE_IMAGES);
if (images != null) {
- for (int i = 0; i < images.length(); i++) {
- final JSONObject imageResponse = images.getJSONObject(i);
- final String title = imageResponse.getString(CACHE_IMAGE_CAPTION);
- final String url = absoluteUrl(imageResponse.getString(CACHE_IMAGE_URL), cache.getGeocode());
+ for (final JsonNode imageResponse: images) {
+ final String title = imageResponse.get(CACHE_IMAGE_CAPTION).asText();
+ final String url = absoluteUrl(imageResponse.get(CACHE_IMAGE_URL).asText(), cache.getGeocode());
// all images are added as spoiler images, although OKAPI has spoiler and non spoiler images
cache.addSpoiler(new Image(url, title));
}
}
- cache.setAttributes(parseAttributes(response.getJSONArray(CACHE_ATTRNAMES), response.optJSONArray(CACHE_ATTR_ACODES)));
+ cache.setAttributes(parseAttributes((ArrayNode) response.path(CACHE_ATTRNAMES), (ArrayNode) response.get(CACHE_ATTR_ACODES)));
//TODO: Store license per cache
//cache.setLicense(response.getString("attribution_note"));
- cache.setWaypoints(parseWaypoints(response.getJSONArray(CACHE_WPTS)), false);
+ cache.setWaypoints(parseWaypoints((ArrayNode) response.path(CACHE_WPTS)), false);
- cache.setInventory(parseTrackables(response.getJSONArray(CACHE_TRACKABLES)));
+ cache.setInventory(parseTrackables((ArrayNode) response.path(CACHE_TRACKABLES)));
- if (!response.isNull(CACHE_IS_WATCHED)) {
- cache.setOnWatchlist(response.getBoolean(CACHE_IS_WATCHED));
+ if (response.has(CACHE_IS_WATCHED)) {
+ cache.setOnWatchlist(response.get(CACHE_IS_WATCHED).asBoolean());
}
- if (!response.isNull(CACHE_MY_NOTES)) {
- cache.setPersonalNote(response.getString(CACHE_MY_NOTES));
+ if (response.hasNonNull(CACHE_MY_NOTES)) {
+ cache.setPersonalNote(response.get(CACHE_MY_NOTES).asText());
cache.parseWaypointsFromNote();
}
- cache.setLogPasswordRequired(response.getBoolean(CACHE_REQ_PASSWORD));
+ cache.setLogPasswordRequired(response.get(CACHE_REQ_PASSWORD).asBoolean());
cache.setDetailedUpdatedNow();
// save full detailed caches
DataStore.saveCache(cache, EnumSet.of(SaveFlag.DB));
- DataStore.saveLogsWithoutTransaction(cache.getGeocode(), parseLogs(response.getJSONArray(CACHE_LATEST_LOGS)));
- } catch (final JSONException e) {
+ DataStore.saveLogsWithoutTransaction(cache.getGeocode(), parseLogs((ArrayNode) response.path(CACHE_LATEST_LOGS)));
+ } catch (ClassCastException | NullPointerException e) {
Log.e("OkapiClient.parseCache", e);
}
return cache;
}
- private static void parseCoreCache(final JSONObject response, final Geocache cache) throws JSONException {
- cache.setGeocode(response.getString(CACHE_CODE));
- cache.setName(response.getString(CACHE_NAME));
+ private static void parseCoreCache(final ObjectNode response, final Geocache cache) {
+ cache.setGeocode(response.get(CACHE_CODE).asText());
+ cache.setName(response.get(CACHE_NAME).asText());
// not used: names
- setLocation(cache, response.getString(CACHE_LOCATION));
- cache.setType(getCacheType(response.getString(CACHE_TYPE)));
+ setLocation(cache, response.get(CACHE_LOCATION).asText());
+ cache.setType(getCacheType(response.get(CACHE_TYPE).asText()));
- final String status = response.getString(CACHE_STATUS);
+ final String status = response.get(CACHE_STATUS).asText();
cache.setDisabled(status.equalsIgnoreCase(CACHE_STATUS_DISABLED));
cache.setArchived(status.equalsIgnoreCase(CACHE_STATUS_ARCHIVED));
cache.setSize(getCacheSize(response));
- cache.setDifficulty((float) response.getDouble(CACHE_DIFFICULTY));
- cache.setTerrain((float) response.getDouble(CACHE_TERRAIN));
+ cache.setDifficulty((float) response.get(CACHE_DIFFICULTY).asDouble());
+ cache.setTerrain((float) response.get(CACHE_TERRAIN).asDouble());
- cache.setInventoryItems(response.getInt(CACHE_TRACKABLES_COUNT));
+ cache.setInventoryItems(response.get(CACHE_TRACKABLES_COUNT).asInt());
- if (!response.isNull(CACHE_IS_FOUND)) {
- cache.setFound(response.getBoolean(CACHE_IS_FOUND));
+ if (response.has(CACHE_IS_FOUND)) {
+ cache.setFound(response.get(CACHE_IS_FOUND).asBoolean());
}
- cache.setHidden(parseDate(response.getString(CACHE_HIDDEN)));
+ cache.setHidden(parseDate(response.get(CACHE_HIDDEN).asText()));
}
private static String absoluteUrl(final String url, final String geocode) {
@@ -447,41 +451,39 @@ final class OkapiClient {
return url;
}
- private static String parseUser(final JSONObject user) throws JSONException {
- return user.getString(USER_USERNAME);
+ private static String parseUser(final JsonNode user) {
+ return user.get(USER_USERNAME).asText();
}
- private static List<LogEntry> parseLogs(final JSONArray logsJSON) {
+ private static List<LogEntry> parseLogs(final ArrayNode logsJSON) {
List<LogEntry> result = null;
- for (int i = 0; i < logsJSON.length(); i++) {
+ for (final JsonNode logResponse: logsJSON) {
try {
- final JSONObject logResponse = logsJSON.getJSONObject(i);
final LogEntry log = new LogEntry(
- parseUser(logResponse.getJSONObject(LOG_USER)),
- parseDate(logResponse.getString(LOG_DATE)).getTime(),
- parseLogType(logResponse.getString(LOG_TYPE)),
- logResponse.getString(LOG_COMMENT).trim());
+ parseUser(logResponse.get(LOG_USER)),
+ parseDate(logResponse.get(LOG_DATE).asText()).getTime(),
+ parseLogType(logResponse.get(LOG_TYPE).asText()),
+ logResponse.get(LOG_COMMENT).asText().trim());
if (result == null) {
result = new ArrayList<>();
}
result.add(log);
- } catch (final JSONException e) {
+ } catch (final NullPointerException e) {
Log.e("OkapiClient.parseLogs", e);
}
}
return result;
}
- private static List<Waypoint> parseWaypoints(final JSONArray wptsJson) {
+ private static List<Waypoint> parseWaypoints(final ArrayNode wptsJson) {
List<Waypoint> result = null;
- for (int i = 0; i < wptsJson.length(); i++) {
+ for (final JsonNode wptResponse: wptsJson) {
try {
- final JSONObject wptResponse = wptsJson.getJSONObject(i);
- final Waypoint wpt = new Waypoint(wptResponse.getString(WPT_NAME),
- parseWptType(wptResponse.getString(WPT_TYPE)),
+ final Waypoint wpt = new Waypoint(wptResponse.get(WPT_NAME).asText(),
+ parseWptType(wptResponse.get(WPT_TYPE).asText()),
false);
- wpt.setNote(wptResponse.getString(WPT_DESCRIPTION));
- final Geopoint pt = parseCoords(wptResponse.getString(WPT_LOCATION));
+ wpt.setNote(wptResponse.get(WPT_DESCRIPTION).asText());
+ final Geopoint pt = parseCoords(wptResponse.get(WPT_LOCATION).asText());
if (pt != null) {
wpt.setCoords(pt);
}
@@ -490,26 +492,25 @@ final class OkapiClient {
}
wpt.setPrefix(wpt.getName());
result.add(wpt);
- } catch (final JSONException e) {
+ } catch (final NullPointerException e) {
Log.e("OkapiClient.parseWaypoints", e);
}
}
return result;
}
- private static List<Trackable> parseTrackables(final JSONArray trackablesJson) {
- if (trackablesJson.length() == 0) {
+ private static List<Trackable> parseTrackables(final ArrayNode trackablesJson) {
+ if (trackablesJson.size() == 0) {
return Collections.emptyList();
}
final List<Trackable> result = new ArrayList<>();
- for (int i = 0; i < trackablesJson.length(); i++) {
+ for (final JsonNode trackableResponse: trackablesJson) {
try {
- final JSONObject trackableResponse = trackablesJson.getJSONObject(i);
final Trackable trk = new Trackable();
- trk.setGeocode(trackableResponse.getString(TRK_GEOCODE));
- trk.setName(trackableResponse.getString(TRK_NAME));
+ trk.setGeocode(trackableResponse.get(TRK_GEOCODE).asText());
+ trk.setName(trackableResponse.get(TRK_NAME).asText());
result.add(trk);
- } catch (final JSONException e) {
+ } catch (final NullPointerException e) {
Log.e("OkapiClient.parseWaypoints", e);
// Don't overwrite internal state with possibly partial result
return null;
@@ -578,7 +579,7 @@ final class OkapiClient {
}
private static Date parseDate(final String date) {
- final String strippedDate = date.replaceAll("\\+0([0-9]){1}\\:00", "+0$100");
+ final String strippedDate = PATTERN_TIMEZONE.matcher(date).replaceAll("$1$20");
try {
return ISO8601DATEFORMAT.parse(strippedDate);
} catch (final ParseException e) {
@@ -597,14 +598,14 @@ final class OkapiClient {
return null;
}
- private static List<String> parseAttributes(final JSONArray nameList, final JSONArray acodeList) {
+ private static List<String> parseAttributes(final ArrayNode nameList, final ArrayNode acodeList) {
final List<String> result = new ArrayList<>();
- for (int i = 0; i < nameList.length(); i++) {
+ for (int i = 0; i < nameList.size(); i++) {
try {
- final String name = nameList.getString(i);
- final int acode = acodeList != null ? Integer.parseInt(acodeList.getString(i).substring(1)) : CacheAttribute.NO_ID;
+ final String name = nameList.get(i).asText();
+ final int acode = acodeList != null ? Integer.parseInt(acodeList.get(i).asText().substring(1)) : CacheAttribute.NO_ID;
final CacheAttribute attr = CacheAttribute.getByOcACode(acode);
if (attr != null) {
@@ -612,7 +613,7 @@ final class OkapiClient {
} else {
result.add(name);
}
- } catch (final JSONException e) {
+ } catch (final NullPointerException e) {
Log.e("OkapiClient.parseAttributes", e);
}
}
@@ -626,27 +627,27 @@ final class OkapiClient {
cache.setCoords(new Geopoint(latitude, longitude));
}
- private static CacheSize getCacheSize(final JSONObject response) {
- if (response.isNull(CACHE_SIZE2)) {
+ private static CacheSize getCacheSize(final ObjectNode response) {
+ if (!response.has(CACHE_SIZE2)) {
return getCacheSizeDeprecated(response);
}
try {
- final String size = response.getString(CACHE_SIZE2);
+ final String size = response.get(CACHE_SIZE2).asText();
return CacheSize.getById(size);
- } catch (final JSONException e) {
+ } catch (final NullPointerException e) {
Log.e("OkapiClient.getCacheSize", e);
return getCacheSizeDeprecated(response);
}
}
- private static CacheSize getCacheSizeDeprecated(final JSONObject response) {
- if (response.isNull(CACHE_SIZE_DEPRECATED)) {
+ private static CacheSize getCacheSizeDeprecated(final ObjectNode response) {
+ if (!response.has(CACHE_SIZE_DEPRECATED)) {
return CacheSize.NOT_CHOSEN;
}
double size = 0;
try {
- size = response.getDouble(CACHE_SIZE_DEPRECATED);
- } catch (final JSONException e) {
+ size = response.get(CACHE_SIZE_DEPRECATED).asDouble();
+ } catch (final NullPointerException e) {
Log.e("OkapiClient.getCacheSize", e);
}
switch ((int) Math.round(size)) {
@@ -734,19 +735,22 @@ final class OkapiClient {
@NonNull
private static JSONResult request(final OCApiConnector connector, final OkapiService service, final Parameters params) {
if (connector == null) {
- return new JSONResult(null);
+ return new JSONResult("unknown OKAPI connector");
}
final String host = connector.getHost();
if (StringUtils.isBlank(host)) {
- return new JSONResult(null);
+ return new JSONResult("unknown OKAPI connector host");
}
params.add("langpref", getPreferredLanguage());
if (connector.getSupportedAuthLevel() == OAuthLevel.Level3) {
- final ImmutablePair<String, String> tokens = Settings.getTokenPair(connector.getTokenPublicPrefKeyId(), connector.getTokenSecretPrefKeyId());
- OAuth.signOAuth(host, service.methodName, "GET", false, params, tokens.left, tokens.right, connector.getCK(), connector.getCS());
+ final OAuthTokens tokens = new OAuthTokens(connector);
+ if (!tokens.isValid()) {
+ return new JSONResult("invalid oauth tokens");
+ }
+ OAuth.signOAuth(host, service.methodName, "GET", false, params, tokens, connector.getCK(), connector.getCS());
} else {
connector.addAuthentication(params);
}
@@ -812,16 +816,7 @@ final class OkapiClient {
return null;
}
- final JSONObject data = result.data;
- if (!data.isNull(USER_UUID)) {
- try {
- return data.getString(USER_UUID);
- } catch (final JSONException e) {
- Log.e("OkapiClient.getUserUUID - uuid", e);
- }
- }
-
- return null;
+ return result.data.path(USER_UUID).asText(null);
}
public static UserInfo getUserInfo(final OCApiLiveConnector connector) {
@@ -835,31 +830,11 @@ final class OkapiClient {
return new UserInfo(StringUtils.EMPTY, 0, UserInfoStatus.getFromOkapiError(error.getResult()));
}
- final JSONObject data = result.data;
-
- String name = StringUtils.EMPTY;
- boolean successUserName = false;
-
- if (!data.isNull(USER_USERNAME)) {
- try {
- name = data.getString(USER_USERNAME);
- successUserName = true;
- } catch (final JSONException e) {
- Log.e("OkapiClient.getUserInfo - name", e);
- }
- }
-
- int finds = 0;
- boolean successFinds = false;
-
- if (!data.isNull(USER_CACHES_FOUND)) {
- try {
- finds = data.getInt(USER_CACHES_FOUND);
- successFinds = true;
- } catch (final JSONException e) {
- Log.e("OkapiClient.getUserInfo - finds", e);
- }
- }
+ final ObjectNode data = result.data;
+ final boolean successUserName = data.has(USER_USERNAME);
+ final String name = data.path(USER_USERNAME).asText();
+ final boolean successFinds = data.has(USER_CACHES_FOUND);
+ final int finds = data.path(USER_CACHES_FOUND).asInt();
return new UserInfo(name, finds, successUserName && successFinds ? UserInfoStatus.SUCCESSFUL : UserInfoStatus.FAILED);
}
@@ -876,7 +851,7 @@ final class OkapiClient {
if (!result.isSuccess) {
return new OkapiError(result.data);
}
- return new OkapiError(new JSONObject());
+ return new OkapiError(new ObjectNode(JsonUtils.factory));
}
/**
@@ -886,21 +861,26 @@ final class OkapiClient {
private static class JSONResult {
public final boolean isSuccess;
- public final JSONObject data;
+ public final ObjectNode data;
public JSONResult(final @Nullable HttpResponse response) {
- final boolean isSuccess = Network.isSuccess(response);
+ final boolean isRequestSuccessful = Network.isSuccess(response);
final String responseData = Network.getResponseDataAlways(response);
- JSONObject data = null;
+ ObjectNode tempData = null;
if (responseData != null) {
try {
- data = new JSONObject(responseData);
- } catch (final JSONException e) {
+ tempData = (ObjectNode) JsonUtils.reader.readTree(responseData);
+ } catch (IOException | ClassCastException e) {
Log.w("JSONResult", e);
}
}
- this.data = data;
- this.isSuccess = isSuccess && data != null;
+ data = tempData;
+ isSuccess = isRequestSuccessful && tempData != null;
+ }
+
+ public JSONResult(final @NonNull String errorMessage) {
+ isSuccess = false;
+ data = new ObjectNode(JsonUtils.factory).putObject("error").put("developer_message", errorMessage);
}
}
}
diff --git a/main/src/cgeo/geocaching/connector/oc/OkapiError.java b/main/src/cgeo/geocaching/connector/oc/OkapiError.java
index 7faf2c7..b847207 100644
--- a/main/src/cgeo/geocaching/connector/oc/OkapiError.java
+++ b/main/src/cgeo/geocaching/connector/oc/OkapiError.java
@@ -2,11 +2,11 @@ package cgeo.geocaching.connector.oc;
import cgeo.geocaching.utils.Log;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
import org.apache.commons.lang3.StringUtils;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
-import org.json.JSONException;
-import org.json.JSONObject;
/**
* Handles the JSON error response from OKAPI
@@ -26,7 +26,7 @@ public class OkapiError {
@NonNull private final OkapiErrors state;
@NonNull private final String message;
- public OkapiError(@Nullable JSONObject data) {
+ public OkapiError(@Nullable ObjectNode data) {
// A null-response is by definition an error (some exception occurred somewhere in the flow)
if (data == null) {
@@ -39,10 +39,10 @@ public class OkapiError {
String localmessage = null;
OkapiErrors localstate = OkapiErrors.UNSPECIFIED;
try {
- JSONObject error = data.getJSONObject("error");
+ final ObjectNode error = (ObjectNode) data.get("error");
// Check reason_stack element to look for the specific oauth problems we want to report back
if (error.has("reason_stack")) {
- String reason = error.getString("reason_stack");
+ final String reason = error.get("reason_stack").asText();
if (StringUtils.contains(reason, "invalid_oauth_request")) {
if (StringUtils.contains(reason, "invalid_timestamp")) {
localstate = OkapiErrors.INVALID_TIMESTAMP;
@@ -53,10 +53,10 @@ public class OkapiError {
}
// Check if we can extract a message as well
if (error.has("developer_message")) {
- localmessage = error.getString("developer_message");
+ localmessage = error.get("developer_message").asText();
assert localmessage != null; // by virtue of defaultString
}
- } catch (JSONException ex) {
+ } catch (ClassCastException | NullPointerException ex) {
Log.d("OkapiError: Failed to parse JSON", ex);
localstate = OkapiErrors.UNSPECIFIED;
}
diff --git a/main/src/cgeo/geocaching/connector/ox/OpenCachingApi.java b/main/src/cgeo/geocaching/connector/ox/OpenCachingApi.java
index b2afff5..21207ec 100644
--- a/main/src/cgeo/geocaching/connector/ox/OpenCachingApi.java
+++ b/main/src/cgeo/geocaching/connector/ox/OpenCachingApi.java
@@ -39,9 +39,9 @@ public class OpenCachingApi {
return null;
}
- private static HttpResponse getRequest(String string, Parameters parameters) {
+ private static HttpResponse getRequest(final String uri, final Parameters parameters) {
parameters.add("Authorization", DEV_KEY);
- return Network.getRequest(string, parameters);
+ return Network.getRequest(uri, parameters);
}
private static Collection<Geocache> importCachesFromResponse(final HttpResponse response, final boolean isDetailed) {
@@ -50,7 +50,7 @@ public class OpenCachingApi {
}
Collection<Geocache> caches;
try {
- caches = new OXGPXParser(StoredList.TEMPORARY_LIST_ID, isDetailed).parse(response.getEntity().getContent(), null);
+ caches = new OXGPXParser(StoredList.TEMPORARY_LIST.id, isDetailed).parse(response.getEntity().getContent(), null);
} catch (Exception e) {
Log.e("Error importing from OpenCaching.com", e);
return Collections.emptyList();
diff --git a/main/src/cgeo/geocaching/files/AbstractFileListActivity.java b/main/src/cgeo/geocaching/files/AbstractFileListActivity.java
index 2a05cbc..fa84df9 100644
--- a/main/src/cgeo/geocaching/files/AbstractFileListActivity.java
+++ b/main/src/cgeo/geocaching/files/AbstractFileListActivity.java
@@ -38,7 +38,7 @@ public abstract class AbstractFileListActivity<T extends ArrayAdapter<File>> ext
private String searchInfo;
@Override
- public void handleMessage(Message msg) {
+ public void handleMessage(final Message msg) {
if (msg.obj != null && waitDialog != null) {
if (searchInfo == null) {
searchInfo = res.getString(R.string.file_searching_in) + " ";
@@ -52,7 +52,7 @@ public abstract class AbstractFileListActivity<T extends ArrayAdapter<File>> ext
private String getDefaultFolders() {
final ArrayList<String> names = new ArrayList<>();
- for (File dir : getExistingBaseFolders()) {
+ for (final File dir : getExistingBaseFolders()) {
names.add(dir.getPath());
}
return StringUtils.join(names, '\n');
@@ -62,7 +62,7 @@ public abstract class AbstractFileListActivity<T extends ArrayAdapter<File>> ext
final private Handler loadFilesHandler = new Handler() {
@Override
- public void handleMessage(Message msg) {
+ public void handleMessage(final Message msg) {
if (waitDialog != null) {
waitDialog.dismiss();
}
@@ -76,17 +76,17 @@ public abstract class AbstractFileListActivity<T extends ArrayAdapter<File>> ext
};
@Override
- public void onCreate(Bundle savedInstanceState) {
+ public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTheme();
setContentView(R.layout.gpx);
- Bundle extras = getIntent().getExtras();
+ final Bundle extras = getIntent().getExtras();
if (extras != null) {
listId = extras.getInt(Intents.EXTRA_LIST_ID);
}
- if (listId <= StoredList.TEMPORARY_LIST_ID) {
+ if (listId <= StoredList.TEMPORARY_LIST.id) {
listId = StoredList.STANDARD_LIST_ID;
}
@@ -100,7 +100,7 @@ public abstract class AbstractFileListActivity<T extends ArrayAdapter<File>> ext
true,
new DialogInterface.OnCancelListener() {
@Override
- public void onCancel(DialogInterface arg0) {
+ public void onCancel(final DialogInterface arg0) {
if (searchingThread != null && searchingThread.isAlive()) {
searchingThread.notifyEnd();
}
@@ -171,7 +171,7 @@ public abstract class AbstractFileListActivity<T extends ArrayAdapter<File>> ext
} else {
Log.w("No external media mounted.");
}
- } catch (Exception e) {
+ } catch (final Exception e) {
Log.e("AbstractFileListActivity.loadFiles.run", e);
}
@@ -181,7 +181,7 @@ public abstract class AbstractFileListActivity<T extends ArrayAdapter<File>> ext
Collections.sort(files, new Comparator<File>() {
@Override
- public int compare(File lhs, File rhs) {
+ public int compare(final File lhs, final File rhs) {
return lhs.getName().compareToIgnoreCase(rhs.getName());
}
});
@@ -189,7 +189,7 @@ public abstract class AbstractFileListActivity<T extends ArrayAdapter<File>> ext
loadFilesHandler.sendMessage(Message.obtain(loadFilesHandler));
}
- private void listDirs(List<File> list, List<File> directories, FileListSelector selector, Handler feedbackHandler) {
+ private void listDirs(final List<File> list, final List<File> directories, final FileListSelector selector, final Handler feedbackHandler) {
for (final File dir : directories) {
FileUtils.listDir(list, dir, selector, feedbackHandler);
}
@@ -204,7 +204,7 @@ public abstract class AbstractFileListActivity<T extends ArrayAdapter<File>> ext
* @return <code>true</code> if the filename belongs to the list
*/
protected boolean filenameBelongsToList(final String filename) {
- for (String ext : extensions) {
+ for (final String ext : extensions) {
if (StringUtils.endsWithIgnoreCase(filename, ext)) {
return true;
}
@@ -213,7 +213,7 @@ public abstract class AbstractFileListActivity<T extends ArrayAdapter<File>> ext
}
protected List<File> getExistingBaseFolders() {
- ArrayList<File> result = new ArrayList<>();
+ final ArrayList<File> result = new ArrayList<>();
for (final File dir : getBaseFolders()) {
if (dir.exists() && dir.isDirectory()) {
result.add(dir);
@@ -245,7 +245,7 @@ public abstract class AbstractFileListActivity<T extends ArrayAdapter<File>> ext
boolean shouldEnd = false;
@Override
- public boolean isSelected(File file) {
+ public boolean isSelected(final File file) {
return filenameBelongsToList(file.getName());
}
@@ -254,7 +254,7 @@ public abstract class AbstractFileListActivity<T extends ArrayAdapter<File>> ext
return shouldEnd;
}
- public synchronized void setShouldEnd(boolean shouldEnd) {
+ public synchronized void setShouldEnd(final boolean shouldEnd) {
this.shouldEnd = shouldEnd;
}
}
diff --git a/main/src/cgeo/geocaching/files/FileTypeDetector.java b/main/src/cgeo/geocaching/files/FileTypeDetector.java
index 389b83a..ab0f032 100644
--- a/main/src/cgeo/geocaching/files/FileTypeDetector.java
+++ b/main/src/cgeo/geocaching/files/FileTypeDetector.java
@@ -10,7 +10,6 @@ import android.content.ContentResolver;
import android.net.Uri;
import java.io.BufferedReader;
-import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@@ -37,8 +36,6 @@ public class FileTypeDetector {
reader = new BufferedReader(new InputStreamReader(is));
type = detectHeader(reader);
reader.close();
- } catch (FileNotFoundException e) {
- Log.e("FileTypeDetector", e);
} catch (IOException e) {
Log.e("FileTypeDetector", e);
} finally {
diff --git a/main/src/cgeo/geocaching/files/GPXImporter.java b/main/src/cgeo/geocaching/files/GPXImporter.java
index 52f68e1..85d12f7 100644
--- a/main/src/cgeo/geocaching/files/GPXImporter.java
+++ b/main/src/cgeo/geocaching/files/GPXImporter.java
@@ -139,10 +139,11 @@ public class GPXImporter {
final String mimeType) {
if (GPX_MIME_TYPES.contains(mimeType)) {
return FileType.GPX;
- } else if (ZIP_MIME_TYPES.contains(mimeType)) {
+ }
+ if (ZIP_MIME_TYPES.contains(mimeType)) {
return FileType.ZIP;
}
- return FileType.UNKNOWN;
+ return FileType.UNKNOWN;
}
private ImportThread getImporterFromFileType(Uri uri,
diff --git a/main/src/cgeo/geocaching/files/GPXParser.java b/main/src/cgeo/geocaching/files/GPXParser.java
index 89ee887..370b8aa 100644
--- a/main/src/cgeo/geocaching/files/GPXParser.java
+++ b/main/src/cgeo/geocaching/files/GPXParser.java
@@ -454,7 +454,7 @@ public abstract class GPXParser extends FileParser {
@Override
public void end(String body) {
- final String[] content = body.split("\\|");
+ final String[] content = StringUtils.split(body, '|');
if (content.length > 0) {
type = content[0].toLowerCase(Locale.US).trim();
}
diff --git a/main/src/cgeo/geocaching/files/IFileSelectionView.java b/main/src/cgeo/geocaching/files/IFileSelectionView.java
index 5bbc1b2..0407ee4 100644
--- a/main/src/cgeo/geocaching/files/IFileSelectionView.java
+++ b/main/src/cgeo/geocaching/files/IFileSelectionView.java
@@ -8,7 +8,7 @@ public interface IFileSelectionView {
String getCurrentFile();
- void setCurrentFile(String string);
+ void setCurrentFile(final String name);
void close();
diff --git a/main/src/cgeo/geocaching/files/InvalidXMLCharacterFilterReader.java b/main/src/cgeo/geocaching/files/InvalidXMLCharacterFilterReader.java
index a7a3e1b..8a089d2 100644
--- a/main/src/cgeo/geocaching/files/InvalidXMLCharacterFilterReader.java
+++ b/main/src/cgeo/geocaching/files/InvalidXMLCharacterFilterReader.java
@@ -1,98 +1,94 @@
-package cgeo.geocaching.files;
-
-import org.apache.commons.lang3.StringUtils;
-
-import java.io.FilterReader;
-import java.io.IOException;
-import java.io.Reader;
-
-/**
- * Filter reader which can filter out invalid XML characters and character references.
- *
- */
-public class InvalidXMLCharacterFilterReader extends FilterReader
-{
-
- public InvalidXMLCharacterFilterReader(Reader in) {
- super(in);
- }
-
- /**
- * Every overload of {@link Reader#read()} method delegates to this one so
- * it is enough to override only this one. <br />
- * To skip invalid characters this method shifts only valid chars to left
- * and returns decreased value of the original read method. So after last
- * valid character there will be some unused chars in the buffer.
- *
- * @return Number of read valid characters or <code>-1</code> if end of the
- * underling reader was reached.
- */
- @Override
- public int read(char[] cbuf, int off, int len) throws IOException {
- int read = super.read(cbuf, off, len);
- // check for end
- if (read == -1) {
- return -1;
- }
- // target position
- int pos = off - 1;
-
- int entityStart = -1;
- for (int readPos = off; readPos < off + read; readPos++) {
- boolean useChar = true;
- switch (cbuf[readPos]) {
- case '&':
- pos++;
- entityStart = readPos;
- break;
- case ';':
- pos++;
- if (entityStart >= 0) {
- int entityLength = readPos - entityStart + 1;
- if (entityLength <= 5) {
- String entity = new String(cbuf, entityStart, entityLength);
- if (StringUtils.startsWith(entity, "&#")) {
- String numberString = StringUtils.substringBetween(entity, "&#", ";");
- final int value;
- if (StringUtils.startsWith(numberString, "x")) {
- value = Integer.parseInt(numberString.substring(1), 16);
- }
- else {
- value = Integer.parseInt(numberString);
- }
- if (!isValidXMLChar((char) value)) {
- pos -= entityLength;
- useChar = false;
- }
- }
- }
- }
- break;
- default:
- if (isValidXMLChar(cbuf[readPos])) {
- pos++;
- } else {
- continue;
- }
- }
- // copy, and skip unwanted characters
- if (pos < readPos && useChar) {
- cbuf[pos] = cbuf[readPos];
- }
- }
- return pos - off + 1;
- }
-
- private static boolean isValidXMLChar(char c) {
- if ((c == 0x9) ||
- (c == 0xA) ||
- (c == 0xD) ||
- ((c >= 0x20) && (c <= 0xD7FF)) ||
- ((c >= 0xE000) && (c <= 0xFFFD)) ||
- ((c >= 0x10000) && (c <= 0x10FFFF)))
- {
- return true;
- }
- return false;
- }
+package cgeo.geocaching.files;
+
+import org.apache.commons.lang3.StringUtils;
+
+import java.io.FilterReader;
+import java.io.IOException;
+import java.io.Reader;
+
+/**
+ * Filter reader which can filter out invalid XML characters and character references.
+ *
+ */
+public class InvalidXMLCharacterFilterReader extends FilterReader
+{
+
+ public InvalidXMLCharacterFilterReader(Reader in) {
+ super(in);
+ }
+
+ /**
+ * Every overload of {@link Reader#read()} method delegates to this one so
+ * it is enough to override only this one. <br />
+ * To skip invalid characters this method shifts only valid chars to left
+ * and returns decreased value of the original read method. So after last
+ * valid character there will be some unused chars in the buffer.
+ *
+ * @return Number of read valid characters or <code>-1</code> if end of the
+ * underling reader was reached.
+ */
+ @Override
+ public int read(char[] cbuf, int off, int len) throws IOException {
+ int read = super.read(cbuf, off, len);
+ // check for end
+ if (read == -1) {
+ return -1;
+ }
+ // target position
+ int pos = off - 1;
+
+ int entityStart = -1;
+ for (int readPos = off; readPos < off + read; readPos++) {
+ boolean useChar = true;
+ switch (cbuf[readPos]) {
+ case '&':
+ pos++;
+ entityStart = readPos;
+ break;
+ case ';':
+ pos++;
+ if (entityStart >= 0) {
+ int entityLength = readPos - entityStart + 1;
+ if (entityLength <= 5) {
+ String entity = new String(cbuf, entityStart, entityLength);
+ if (StringUtils.startsWith(entity, "&#")) {
+ String numberString = StringUtils.substringBetween(entity, "&#", ";");
+ final int value;
+ if (StringUtils.startsWith(numberString, "x")) {
+ value = Integer.parseInt(numberString.substring(1), 16);
+ }
+ else {
+ value = Integer.parseInt(numberString);
+ }
+ if (!isValidXMLChar((char) value)) {
+ pos -= entityLength;
+ useChar = false;
+ }
+ }
+ }
+ }
+ break;
+ default:
+ if (isValidXMLChar(cbuf[readPos])) {
+ pos++;
+ } else {
+ continue;
+ }
+ }
+ // copy, and skip unwanted characters
+ if (pos < readPos && useChar) {
+ cbuf[pos] = cbuf[readPos];
+ }
+ }
+ return pos - off + 1;
+ }
+
+ private static boolean isValidXMLChar(char c) {
+ return (c == 0x9) ||
+ (c == 0xA) ||
+ (c == 0xD) ||
+ ((c >= 0x20) && (c <= 0xD7FF)) ||
+ ((c >= 0xE000) && (c <= 0xFFFD)) ||
+ ((c >= 0x10000) && (c <= 0x10FFFF));
+ }
} \ No newline at end of file
diff --git a/main/src/cgeo/geocaching/files/LocParser.java b/main/src/cgeo/geocaching/files/LocParser.java
index 2871d77..13f8cca 100644
--- a/main/src/cgeo/geocaching/files/LocParser.java
+++ b/main/src/cgeo/geocaching/files/LocParser.java
@@ -88,7 +88,7 @@ public final class LocParser extends FileParser {
}
// >> premium only
- final String[] points = fileContent.split("<waypoint>");
+ final String[] points = StringUtils.splitByWholeSeparator(fileContent, "<waypoint>");
// parse coordinates
for (String pointString : points) {
diff --git a/main/src/cgeo/geocaching/files/SimpleDirChooser.java b/main/src/cgeo/geocaching/files/SimpleDirChooser.java
index 2aadf16..0139206 100644
--- a/main/src/cgeo/geocaching/files/SimpleDirChooser.java
+++ b/main/src/cgeo/geocaching/files/SimpleDirChooser.java
@@ -263,7 +263,7 @@ public class SimpleDirChooser extends AbstractListActivity {
private boolean checked = false;
private boolean writeable = false;
- private static Comparator<Option> NAME_COMPARATOR = new Comparator<SimpleDirChooser.Option>() {
+ private final static Comparator<Option> NAME_COMPARATOR = new Comparator<SimpleDirChooser.Option>() {
@Override
public int compare(final Option lhs, final Option rhs) {
diff --git a/main/src/cgeo/geocaching/filter/PopularityFilter.java b/main/src/cgeo/geocaching/filter/PopularityFilter.java
index a0244b9..0fc807d 100644
--- a/main/src/cgeo/geocaching/filter/PopularityFilter.java
+++ b/main/src/cgeo/geocaching/filter/PopularityFilter.java
@@ -29,8 +29,7 @@ class PopularityFilter extends AbstractFilter {
@Override
public List<IFilter> getFilters() {
final List<IFilter> filters = new ArrayList<>(FAVORITES.length);
- for (int i = 0; i < FAVORITES.length; i++) {
- final int minRange = FAVORITES[i];
+ for (final int minRange : FAVORITES) {
final int maxRange = Integer.MAX_VALUE;
final String range = "> " + minRange;
final String name = CgeoApplication.getInstance().getResources().getQuantityString(R.plurals.favorite_points, minRange, range);
diff --git a/main/src/cgeo/geocaching/filter/PopularityRatioFilter.java b/main/src/cgeo/geocaching/filter/PopularityRatioFilter.java
index a04f219..ed8c074 100644
--- a/main/src/cgeo/geocaching/filter/PopularityRatioFilter.java
+++ b/main/src/cgeo/geocaching/filter/PopularityRatioFilter.java
@@ -53,8 +53,7 @@ class PopularityRatioFilter extends AbstractFilter {
@Override
public List<IFilter> getFilters() {
final List<IFilter> filters = new ArrayList<>(RATIOS.length);
- for (int i = 0; i < RATIOS.length; i++) {
- final int minRange = RATIOS[i];
+ for (final int minRange : RATIOS) {
final int maxRange = Integer.MAX_VALUE;
final String name = "> " + minRange + " " + CgeoApplication.getInstance().getResources().getString(R.string.percent_favorite_points);
filters.add(new PopularityRatioFilter(name, minRange, maxRange));
diff --git a/main/src/cgeo/geocaching/gcvote/GCVote.java b/main/src/cgeo/geocaching/gcvote/GCVote.java
index 8de3edc..d42bb34 100644
--- a/main/src/cgeo/geocaching/gcvote/GCVote.java
+++ b/main/src/cgeo/geocaching/gcvote/GCVote.java
@@ -20,7 +20,6 @@ import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
-import java.util.Locale;
import java.util.Map;
import java.util.regex.Pattern;
@@ -275,10 +274,6 @@ public final class GCVote {
return rating >= MIN_RATING && rating <= MAX_RATING;
}
- public static String getRatingText(final float rating) {
- return String.format(Locale.getDefault(), "%.1f", rating);
- }
-
public static boolean isVotingPossible(final Geocache cache) {
return Settings.isGCvoteLogin() && StringUtils.isNotBlank(cache.getGuid()) && cache.supportsGCVote();
}
diff --git a/main/src/cgeo/geocaching/geopoint/Viewport.java b/main/src/cgeo/geocaching/geopoint/Viewport.java
index ba0e040..a48b0a1 100644
--- a/main/src/cgeo/geocaching/geopoint/Viewport.java
+++ b/main/src/cgeo/geocaching/geopoint/Viewport.java
@@ -79,6 +79,22 @@ public final class Viewport {
&& coords.getLatitudeE6() <= topRight.getLatitudeE6();
}
+ /**
+ * Count the number of points present in the viewport.
+ *
+ * @param points a collection of (possibly null) points
+ * @return the number of non-null points in the viewport
+ */
+ public int count(final @NonNull Collection<? extends ICoordinates> points) {
+ int total = 0;
+ for (ICoordinates point: points) {
+ if (point != null && contains(point)) {
+ total += 1;
+ }
+ }
+ return total;
+ }
+
@Override
public String toString() {
return "(" + bottomLeft.toString() + "," + topRight.toString() + ")";
diff --git a/main/src/cgeo/geocaching/list/AbstractList.java b/main/src/cgeo/geocaching/list/AbstractList.java
index 9b57b3a..5a20b9d 100644
--- a/main/src/cgeo/geocaching/list/AbstractList.java
+++ b/main/src/cgeo/geocaching/list/AbstractList.java
@@ -8,7 +8,7 @@ public abstract class AbstractList {
public final int id;
public final String title;
- private static SparseArray<AbstractList> LISTS = new SparseArray<>();
+ private final static SparseArray<AbstractList> LISTS = new SparseArray<>();
public AbstractList(final int id, final String title) {
this.id = id;
diff --git a/main/src/cgeo/geocaching/list/StoredList.java b/main/src/cgeo/geocaching/list/StoredList.java
index 53632a0..abb6af1 100644
--- a/main/src/cgeo/geocaching/list/StoredList.java
+++ b/main/src/cgeo/geocaching/list/StoredList.java
@@ -24,12 +24,12 @@ import java.util.Comparator;
import java.util.List;
public final class StoredList extends AbstractList {
- public static final int TEMPORARY_LIST_ID = 0;
- public static final StoredList TEMPORARY_LIST = new StoredList(TEMPORARY_LIST_ID, "<temporary>", 0); // Never displayed
+ private static final int TEMPORARY_LIST_ID = 0;
+ public static final StoredList TEMPORARY_LIST = new StoredList(TEMPORARY_LIST_ID, "<temporary>", 0); // Never displayed
public static final int STANDARD_LIST_ID = 1;
private final int count; // this value is only valid as long as the list is not changed by other database operations
- public StoredList(int id, String title, int count) {
+ public StoredList(final int id, final String title, final int count) {
super(id, title);
this.count = count;
}
@@ -48,7 +48,7 @@ public final class StoredList extends AbstractList {
}
@Override
- public boolean equals(Object obj) {
+ public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
@@ -69,10 +69,6 @@ public final class StoredList extends AbstractList {
res = app.getResources();
}
- public void promptForListSelection(final int titleId, @NonNull final Action1<Integer> runAfterwards) {
- promptForListSelection(titleId, runAfterwards, false, -1);
- }
-
public void promptForListSelection(final int titleId, @NonNull final Action1<Integer> runAfterwards, final boolean onlyConcreteLists, final int exceptListId) {
promptForListSelection(titleId, runAfterwards, onlyConcreteLists, exceptListId, StringUtils.EMPTY);
}
@@ -81,18 +77,18 @@ public final class StoredList extends AbstractList {
final List<AbstractList> lists = getMenuLists(onlyConcreteLists, exceptListId);
final List<CharSequence> listsTitle = new ArrayList<>();
- for (AbstractList list : lists) {
+ for (final AbstractList list : lists) {
listsTitle.add(list.getTitleAndCount());
}
final CharSequence[] items = new CharSequence[listsTitle.size()];
final Activity activity = activityRef.get();
- AlertDialog.Builder builder = new AlertDialog.Builder(activity);
+ final AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setTitle(res.getString(titleId));
builder.setItems(listsTitle.toArray(items), new DialogInterface.OnClickListener() {
@Override
- public void onClick(DialogInterface dialogInterface, int itemId) {
+ public void onClick(final DialogInterface dialogInterface, final int itemId) {
final AbstractList list = lists.get(itemId);
if (list == PseudoList.NEW_LIST) {
// create new list on the fly
@@ -106,12 +102,12 @@ public final class StoredList extends AbstractList {
builder.create().show();
}
- public static List<AbstractList> getMenuLists(boolean onlyConcreteLists, int exceptListId) {
+ public static List<AbstractList> getMenuLists(final boolean onlyConcreteLists, final int exceptListId) {
final List<AbstractList> lists = new ArrayList<>();
lists.addAll(getSortedLists());
- if (exceptListId > StoredList.TEMPORARY_LIST_ID) {
- StoredList exceptList = DataStore.getList(exceptListId);
+ if (exceptListId > StoredList.TEMPORARY_LIST.id) {
+ final StoredList exceptList = DataStore.getList(exceptListId);
if (exceptList != null) {
lists.remove(exceptList);
}
@@ -138,7 +134,7 @@ public final class StoredList extends AbstractList {
Collections.sort(lists, new Comparator<StoredList>() {
@Override
- public int compare(StoredList lhs, StoredList rhs) {
+ public int compare(final StoredList lhs, final StoredList rhs) {
// have the standard list at the top
if (lhs.id == STANDARD_LIST_ID) {
return -1;
@@ -153,7 +149,7 @@ public final class StoredList extends AbstractList {
return lists;
}
- public void promptForListCreation(@NonNull final Action1<Integer> runAfterwards, String newListName) {
+ public void promptForListCreation(@NonNull final Action1<Integer> runAfterwards, final String newListName) {
handleListNameInput(newListName, R.string.list_dialog_create_title, R.string.list_dialog_create, new Action1<String>() {
// We need to update the list cache by creating a new StoredList object here.
@@ -177,7 +173,7 @@ public final class StoredList extends AbstractList {
});
}
- private void handleListNameInput(final String defaultValue, int dialogTitle, int buttonTitle, final Action1<String> runnable) {
+ private void handleListNameInput(final String defaultValue, final int dialogTitle, final int buttonTitle, final Action1<String> runnable) {
final Activity activity = activityRef.get();
if (activity == null) {
return;
@@ -187,7 +183,7 @@ public final class StoredList extends AbstractList {
@Override
public void call(final String input) {
// remove whitespaces added by autocompletion of Android keyboard
- String listName = StringUtils.trim(input);
+ final String listName = StringUtils.trim(input);
if (StringUtils.isNotBlank(listName)) {
runnable.call(listName);
}
@@ -225,8 +221,8 @@ public final class StoredList extends AbstractList {
/**
* Return the given list, if it is a concrete list. Return the default list otherwise.
*/
- public static int getConcreteList(int listId) {
- if (listId == PseudoList.ALL_LIST.id || listId == TEMPORARY_LIST_ID || listId == PseudoList.HISTORY_LIST.id) {
+ public static int getConcreteList(final int listId) {
+ if (listId == PseudoList.ALL_LIST.id || listId == TEMPORARY_LIST.id || listId == PseudoList.HISTORY_LIST.id) {
return STANDARD_LIST_ID;
}
return listId;
diff --git a/main/src/cgeo/geocaching/maps/CGeoMap.java b/main/src/cgeo/geocaching/maps/CGeoMap.java
index 2ca0cfd..4b3132f 100644
--- a/main/src/cgeo/geocaching/maps/CGeoMap.java
+++ b/main/src/cgeo/geocaching/maps/CGeoMap.java
@@ -204,7 +204,6 @@ public class CGeoMap extends AbstractMap implements ViewFactory {
private static BlockingQueue<Runnable> downloadQueue = new ArrayBlockingQueue<>(1);
private static ThreadPoolExecutor downloadExecutor = new ThreadPoolExecutor(1, 1, 60, TimeUnit.SECONDS, downloadQueue, new ThreadPoolExecutor.DiscardOldestPolicy());
private static BlockingQueue<Runnable> loadQueue = new ArrayBlockingQueue<>(1);
-
private static ThreadPoolExecutor loadExecutor = new ThreadPoolExecutor(1, 1, 60, TimeUnit.SECONDS, loadQueue, new ThreadPoolExecutor.DiscardOldestPolicy());
// handlers
/** Updates the titles */
@@ -373,21 +372,7 @@ public class CGeoMap extends AbstractMap implements ViewFactory {
}
protected void countVisibleCaches() {
- final List<Geocache> protectedCaches = caches.getAsList();
-
- int count = 0;
- if (!protectedCaches.isEmpty()) {
- final Viewport viewport = mapView.getViewport();
-
- for (final Geocache cache : protectedCaches) {
- if (cache != null && cache.getCoords() != null) {
- if (viewport.contains(cache)) {
- count++;
- }
- }
- }
- }
- cachesCnt = count;
+ cachesCnt = mapView.getViewport().count(caches.getAsList());
}
@Override
@@ -506,7 +491,7 @@ public class CGeoMap extends AbstractMap implements ViewFactory {
}
prepareFilterBar();
- if (!app.isLiveMapHintShownInThisSession() && !Settings.getHideLiveMapHint() && Settings.getLiveMapHintShowCount() <= 3) {
+ if (!app.isLiveMapHintShownInThisSession() && Settings.getLiveMapHintShowCount() <= 3) {
LiveMapInfoDialogBuilder.create(activity).show();
}
}
@@ -708,7 +693,7 @@ public class CGeoMap extends AbstractMap implements ViewFactory {
public void call(final Integer selectedListId) {
storeCaches(geocodes, selectedListId);
}
- }, true, StoredList.TEMPORARY_LIST_ID);
+ }, true, StoredList.TEMPORARY_LIST.id);
} else {
storeCaches(geocodes, StoredList.STANDARD_LIST_ID);
}
@@ -906,7 +891,7 @@ public class CGeoMap extends AbstractMap implements ViewFactory {
// Set center of map to my location if appropriate.
private void myLocationInMiddle(final IGeoData geo) {
- if (followMyLocation && !geo.isPseudoLocation()) {
+ if (followMyLocation) {
centerMap(geo.getCoords());
}
}
@@ -923,7 +908,6 @@ public class CGeoMap extends AbstractMap implements ViewFactory {
private static final float MIN_LOCATION_DELTA = 0.01f;
Location currentLocation = new Location("");
- boolean locationValid = false;
float currentHeading;
private long timeLastPositionOverlayCalculation = 0;
@@ -938,15 +922,9 @@ public class CGeoMap extends AbstractMap implements ViewFactory {
@Override
public void updateGeoDir(final IGeoData geo, final float dir) {
- if (geo.isPseudoLocation()) {
- locationValid = false;
- } else {
- locationValid = true;
-
- currentLocation = geo.getLocation();
- currentHeading = DirectionProvider.getDirectionNow(dir);
- repaintPositionOverlay();
- }
+ currentLocation = geo.getLocation();
+ currentHeading = DirectionProvider.getDirectionNow(dir);
+ repaintPositionOverlay();
}
/**
@@ -960,16 +938,16 @@ public class CGeoMap extends AbstractMap implements ViewFactory {
try {
final CGeoMap map = mapRef.get();
if (map != null) {
- final boolean needsRepaintForDistance = needsRepaintForDistance();
+ final boolean needsRepaintForDistanceOrAccuracy = needsRepaintForDistanceOrAccuracy();
final boolean needsRepaintForHeading = needsRepaintForHeading();
- if (needsRepaintForDistance) {
+ if (needsRepaintForDistanceOrAccuracy) {
if (map.followMyLocation) {
map.centerMap(new Geopoint(currentLocation));
}
}
- if (needsRepaintForDistance || needsRepaintForHeading) {
+ if (needsRepaintForDistanceOrAccuracy || needsRepaintForHeading) {
map.overlayPositionAndScale.setCoordinates(currentLocation);
map.overlayPositionAndScale.setHeading(currentHeading);
map.mapView.repaintRequired(map.overlayPositionAndScale);
@@ -989,11 +967,7 @@ public class CGeoMap extends AbstractMap implements ViewFactory {
return Math.abs(AngleUtils.difference(currentHeading, map.overlayPositionAndScale.getHeading())) > MIN_HEADING_DELTA;
}
- boolean needsRepaintForDistance() {
- if (!locationValid) {
- return false;
- }
-
+ boolean needsRepaintForDistanceOrAccuracy() {
final CGeoMap map = mapRef.get();
if (map == null) {
return false;
@@ -1002,6 +976,9 @@ public class CGeoMap extends AbstractMap implements ViewFactory {
float dist = Float.MAX_VALUE;
if (lastLocation != null) {
+ if (lastLocation.getAccuracy() != currentLocation.getAccuracy()) {
+ return true;
+ }
dist = currentLocation.distanceTo(lastLocation);
}
@@ -1028,7 +1005,7 @@ public class CGeoMap extends AbstractMap implements ViewFactory {
displayPoint(coordsIntent);
loadTimer = Subscriptions.empty();
} else {
- loadTimer = startLoadTimer();
+ loadTimer = Schedulers.newThread().createWorker().schedulePeriodically(new LoadTimerAction(this), 0, 250, TimeUnit.MILLISECONDS);
}
return loadTimer;
}
@@ -1085,13 +1062,6 @@ public class CGeoMap extends AbstractMap implements ViewFactory {
}
/**
- * loading timer Triggers every 250ms and checks for viewport change and starts a {@link LoadRunnable}.
- */
- private Subscription startLoadTimer() {
- return Schedulers.newThread().createWorker().schedulePeriodically(new LoadTimerAction(this), 0, 250, TimeUnit.MILLISECONDS);
- }
-
- /**
* get if map is loading something
*
* @return
@@ -1239,9 +1209,6 @@ public class CGeoMap extends AbstractMap implements ViewFactory {
//render
displayExecutor.execute(new DisplayRunnable(this));
- } catch (final ThreadDeath e) {
- Log.d("DownloadThread stopped");
- displayHandler.sendEmptyMessage(UPDATE_TITLE);
} finally {
showProgressHandler.sendEmptyMessage(HIDE_PROGRESS); // hide progress
}
@@ -1301,9 +1268,6 @@ public class CGeoMap extends AbstractMap implements ViewFactory {
}
displayHandler.sendEmptyMessage(UPDATE_TITLE);
- } catch (final ThreadDeath e) {
- Log.d("DisplayThread stopped");
- displayHandler.sendEmptyMessage(UPDATE_TITLE);
} finally {
showProgressHandler.sendEmptyMessage(HIDE_PROGRESS);
}
diff --git a/main/src/cgeo/geocaching/network/HtmlImage.java b/main/src/cgeo/geocaching/network/HtmlImage.java
index 31edc9f..4a5c506 100644
--- a/main/src/cgeo/geocaching/network/HtmlImage.java
+++ b/main/src/cgeo/geocaching/network/HtmlImage.java
@@ -89,7 +89,7 @@ public class HtmlImage implements Html.ImageGetter {
final private int maxWidth;
final private int maxHeight;
final private Resources resources;
- final private TextView view;
+ protected final TextView view;
// Background loading
final private PublishSubject<Observable<String>> loading = PublishSubject.create();
@@ -208,12 +208,7 @@ public class HtmlImage implements Html.ImageGetter {
private Pair<BitmapDrawable, Boolean> loadFromDisk() {
final Pair<Bitmap, Boolean> loadResult = loadImageFromStorage(url, pseudoGeocode, shared);
- final Bitmap bitmap = loadResult.getLeft();
- return new ImmutablePair<>(bitmap != null ?
- ImageUtils.scaleBitmapToFitDisplay(bitmap) :
- null,
- loadResult.getRight()
- );
+ return scaleImage(loadResult);
}
private void downloadAndSave(final Subscriber<? super BitmapDrawable> subscriber) {
@@ -254,6 +249,15 @@ public class HtmlImage implements Html.ImageGetter {
});
}
+ @SuppressWarnings("static-method")
+ protected Pair<BitmapDrawable, Boolean> scaleImage(final Pair<Bitmap, Boolean> loadResult) {
+ final Bitmap bitmap = loadResult.getLeft();
+ return new ImmutablePair<>(bitmap != null ?
+ ImageUtils.scaleBitmapToFitDisplay(bitmap) :
+ null,
+ loadResult.getRight());
+ }
+
public Observable<String> waitForEndObservable(@Nullable final CancellableHandler handler) {
if (handler != null) {
handler.unsubscribeIfCancelled(subscription);
diff --git a/main/src/cgeo/geocaching/network/Network.java b/main/src/cgeo/geocaching/network/Network.java
index ec6ec4f..40f7f7e 100644
--- a/main/src/cgeo/geocaching/network/Network.java
+++ b/main/src/cgeo/geocaching/network/Network.java
@@ -2,6 +2,7 @@ package cgeo.geocaching.network;
import cgeo.geocaching.files.LocalStorage;
import cgeo.geocaching.settings.Settings;
+import cgeo.geocaching.utils.JsonUtils;
import cgeo.geocaching.utils.Log;
import cgeo.geocaching.utils.TextUtils;
@@ -26,11 +27,12 @@ import ch.boye.httpclientandroidlib.params.CoreConnectionPNames;
import ch.boye.httpclientandroidlib.params.CoreProtocolPNames;
import ch.boye.httpclientandroidlib.params.HttpParams;
import ch.boye.httpclientandroidlib.util.EntityUtils;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
import org.apache.commons.lang3.CharEncoding;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.jdt.annotation.Nullable;
-import org.json.JSONException;
-import org.json.JSONObject;
import android.content.Context;
import android.net.ConnectivityManager;
@@ -43,6 +45,7 @@ import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
+import java.util.regex.Pattern;
public abstract class Network {
@@ -51,7 +54,7 @@ public abstract class Network {
/** Native user agent, taken from a Android 2.2 Nexus **/
private final static String NATIVE_USER_AGENT = "Mozilla/5.0 (Linux; U; Android 2.2; en-us; Nexus One Build/FRF91) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1";
- private static final String PATTERN_PASSWORD = "(?<=[\\?&])[Pp]ass(w(or)?d)?=[^&#$]+";
+ private static final Pattern PATTERN_PASSWORD = Pattern.compile("(?<=[\\?&])[Pp]ass(w(or)?d)?=[^&#$]+");
private final static HttpParams clientParams = new BasicHttpParams();
@@ -63,7 +66,7 @@ public abstract class Network {
}
private static String hidePassword(final String message) {
- return message.replaceAll(PATTERN_PASSWORD, "password=***");
+ return PATTERN_PASSWORD.matcher(message).replaceAll("password=***");
}
private static HttpClient getHttpClient() {
@@ -107,14 +110,14 @@ public abstract class Network {
* @return the HTTP response, or null in case of an encoding error params
*/
@Nullable
- public static HttpResponse postJsonRequest(final String uri, final JSONObject json) {
+ public static HttpResponse postJsonRequest(final String uri, final ObjectNode json) {
HttpPost request = new HttpPost(uri);
request.addHeader("Content-Type", "application/json; charset=utf-8");
if (json != null) {
try {
request.setEntity(new StringEntity(json.toString(), CharEncoding.UTF_8));
} catch (UnsupportedEncodingException e) {
- Log.e("postJsonRequest:JSON Entity: UnsupportedEncodingException");
+ Log.e("postJsonRequest:JSON Entity: UnsupportedEncodingException", e);
return null;
}
}
@@ -344,14 +347,14 @@ public abstract class Network {
* @return a JSON object if the request was successful and the body could be decoded, <code>null</code> otherwise
*/
@Nullable
- public static JSONObject requestJSON(final String uri, @Nullable final Parameters params) {
+ public static ObjectNode requestJSON(final String uri, @Nullable final Parameters params) {
final HttpResponse response = request("GET", uri, params, new Parameters("Accept", "application/json, text/javascript, */*; q=0.01"), null);
final String responseData = getResponseData(response, false);
if (responseData != null) {
try {
- return new JSONObject(responseData);
- } catch (final JSONException e) {
- Log.w("Network.requestJSON", e);
+ return (ObjectNode) JsonUtils.reader.readTree(responseData);
+ } catch (final IOException e) {
+ Log.w("requestJSON", e);
}
}
diff --git a/main/src/cgeo/geocaching/network/OAuth.java b/main/src/cgeo/geocaching/network/OAuth.java
index cfc62fc..c23ffbf 100644
--- a/main/src/cgeo/geocaching/network/OAuth.java
+++ b/main/src/cgeo/geocaching/network/OAuth.java
@@ -6,7 +6,6 @@ import ch.boye.httpclientandroidlib.NameValuePair;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.jdt.annotation.Nullable;
import java.util.ArrayList;
import java.util.Date;
@@ -18,8 +17,7 @@ public class OAuth {
final String method,
final boolean https,
final Parameters params,
- @Nullable final String token,
- @Nullable final String tokenSecret,
+ final OAuthTokens tokens,
final String consumerKey,
final String consumerSecret) {
params.put(
@@ -27,7 +25,7 @@ public class OAuth {
"oauth_nonce", CryptUtils.md5(Long.toString(System.currentTimeMillis())),
"oauth_signature_method", "HMAC-SHA1",
"oauth_timestamp", Long.toString(new Date().getTime() / 1000),
- "oauth_token", StringUtils.defaultString(token),
+ "oauth_token", StringUtils.defaultString(tokens.getTokenPublic()),
"oauth_version", "1.0");
params.sort();
@@ -36,7 +34,7 @@ public class OAuth {
paramsEncoded.add(nameValue.getName() + "=" + OAuth.percentEncode(nameValue.getValue()));
}
- final String keysPacked = consumerSecret + "&" + StringUtils.defaultString(tokenSecret); // both even if empty some of them!
+ final String keysPacked = consumerSecret + "&" + StringUtils.defaultString(tokens.getTokenSecret()); // both even if empty some of them!
final @NonNull String joinedParams = StringUtils.join(paramsEncoded.toArray(), '&');
final String requestPacked = method + "&" + OAuth.percentEncode((https ? "https" : "http") + "://" + host + path) + "&" + OAuth.percentEncode(joinedParams);
params.put("oauth_signature", CryptUtils.base64Encode(CryptUtils.hashHmac(requestPacked, keysPacked)));
@@ -48,7 +46,7 @@ public class OAuth {
* @param url
* @return
*/
- static String percentEncode(@NonNull String url) {
+ static String percentEncode(@NonNull final String url) {
return StringUtils.replace(Network.rfc3986URLEncode(url), "*", "%2A");
}
}
diff --git a/main/src/cgeo/geocaching/network/OAuthAuthorizationActivity.java b/main/src/cgeo/geocaching/network/OAuthAuthorizationActivity.java
index eb56f0b..5efea02 100644
--- a/main/src/cgeo/geocaching/network/OAuthAuthorizationActivity.java
+++ b/main/src/cgeo/geocaching/network/OAuthAuthorizationActivity.java
@@ -40,6 +40,8 @@ public abstract class OAuthAuthorizationActivity extends AbstractActivity {
private static final int STATUS_ERROR = 0;
private static final int STATUS_SUCCESS = 1;
private static final int STATUS_ERROR_EXT_MSG = 2;
+ private static final Pattern PARAMS_PATTERN_1 = Pattern.compile("oauth_token=([\\w_.-]+)");
+ private static final Pattern PARAMS_PATTERN_2 = Pattern.compile("oauth_token_secret=([\\w_.-]+)");
@NonNull private String host = StringUtils.EMPTY;
@NonNull private String pathRequest = StringUtils.EMPTY;
@@ -51,18 +53,16 @@ public abstract class OAuthAuthorizationActivity extends AbstractActivity {
@NonNull private String callback = StringUtils.EMPTY;
private String OAtoken = null;
private String OAtokenSecret = null;
- private final Pattern paramsPattern1 = Pattern.compile("oauth_token=([a-zA-Z0-9\\-\\_.]+)");
- private final Pattern paramsPattern2 = Pattern.compile("oauth_token_secret=([a-zA-Z0-9\\-\\_.]+)");
@InjectView(R.id.start) protected Button startButton;
@InjectView(R.id.auth_1) protected TextView auth_1;
@InjectView(R.id.auth_2) protected TextView auth_2;
private ProgressDialog requestTokenDialog = null;
private ProgressDialog changeTokensDialog = null;
- private Handler requestTokenHandler = new Handler() {
+ private final Handler requestTokenHandler = new Handler() {
@Override
- public void handleMessage(Message msg) {
+ public void handleMessage(final Message msg) {
if (requestTokenDialog != null && requestTokenDialog.isShowing()) {
requestTokenDialog.dismiss();
}
@@ -85,10 +85,10 @@ public abstract class OAuthAuthorizationActivity extends AbstractActivity {
};
- private Handler changeTokensHandler = new Handler() {
+ private final Handler changeTokensHandler = new Handler() {
@Override
- public void handleMessage(Message msg) {
+ public void handleMessage(final Message msg) {
if (changeTokensDialog != null && changeTokensDialog.isShowing()) {
changeTokensDialog.dismiss();
}
@@ -105,10 +105,10 @@ public abstract class OAuthAuthorizationActivity extends AbstractActivity {
};
@Override
- public void onCreate(Bundle savedInstanceState) {
+ public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState, R.layout.authorization_activity);
- Bundle extras = getIntent().getExtras();
+ final Bundle extras = getIntent().getExtras();
if (extras != null) {
host = BundleUtils.getString(extras, Intents.EXTRA_OAUTH_HOST, host);
pathRequest = BundleUtils.getString(extras, Intents.EXTRA_OAUTH_PATH_REQUEST, pathRequest);
@@ -125,7 +125,7 @@ public abstract class OAuthAuthorizationActivity extends AbstractActivity {
auth_1.setText(getAuthExplainShort());
auth_2.setText(getAuthExplainLong());
- ImmutablePair<String, String> tempToken = getTempTokens();
+ final ImmutablePair<String, String> tempToken = getTempTokens();
OAtoken = tempToken.left;
OAtokenSecret = tempToken.right;
@@ -167,7 +167,7 @@ public abstract class OAuthAuthorizationActivity extends AbstractActivity {
final Parameters params = new Parameters();
params.put("oauth_callback", callback);
final String method = "GET";
- OAuth.signOAuth(host, pathRequest, method, https, params, null, null, consumerKey, consumerSecret);
+ OAuth.signOAuth(host, pathRequest, method, https, params, new OAuthTokens(null, null), consumerKey, consumerSecret);
final HttpResponse response = Network.getRequest(getUrlPrefix() + host + pathRequest, params);
if (Network.isSuccess(response)) {
@@ -176,11 +176,11 @@ public abstract class OAuthAuthorizationActivity extends AbstractActivity {
int status = STATUS_ERROR;
if (StringUtils.isNotBlank(line)) {
assert line != null;
- final MatcherWrapper paramsMatcher1 = new MatcherWrapper(paramsPattern1, line);
+ final MatcherWrapper paramsMatcher1 = new MatcherWrapper(PARAMS_PATTERN_1, line);
if (paramsMatcher1.find()) {
OAtoken = paramsMatcher1.group(1);
}
- final MatcherWrapper paramsMatcher2 = new MatcherWrapper(paramsPattern2, line);
+ final MatcherWrapper paramsMatcher2 = new MatcherWrapper(PARAMS_PATTERN_2, line);
if (paramsMatcher2.find()) {
OAtokenSecret = paramsMatcher2.group(1);
}
@@ -193,9 +193,7 @@ public abstract class OAuthAuthorizationActivity extends AbstractActivity {
final String encodedParams = EntityUtils.toString(new UrlEncodedFormEntity(paramsBrowser));
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(getUrlPrefix() + host + pathAuthorize + "?" + encodedParams)));
status = STATUS_SUCCESS;
- } catch (ParseException e) {
- Log.e("OAuthAuthorizationActivity.requestToken", e);
- } catch (IOException e) {
+ } catch (ParseException | IOException e) {
Log.e("OAuthAuthorizationActivity.requestToken", e);
}
}
@@ -221,17 +219,17 @@ public abstract class OAuthAuthorizationActivity extends AbstractActivity {
final Parameters params = new Parameters("oauth_verifier", verifier);
final String method = "POST";
- OAuth.signOAuth(host, pathAccess, method, https, params, OAtoken, OAtokenSecret, consumerKey, consumerSecret);
+ OAuth.signOAuth(host, pathAccess, method, https, params, new OAuthTokens(OAtoken, OAtokenSecret), consumerKey, consumerSecret);
final String line = StringUtils.defaultString(Network.getResponseData(Network.postRequest(getUrlPrefix() + host + pathAccess, params)));
OAtoken = "";
OAtokenSecret = "";
- final MatcherWrapper paramsMatcher1 = new MatcherWrapper(paramsPattern1, line);
+ final MatcherWrapper paramsMatcher1 = new MatcherWrapper(PARAMS_PATTERN_1, line);
if (paramsMatcher1.find()) {
OAtoken = paramsMatcher1.group(1);
}
- final MatcherWrapper paramsMatcher2 = new MatcherWrapper(paramsPattern2, line);
+ final MatcherWrapper paramsMatcher2 = new MatcherWrapper(PARAMS_PATTERN_2, line);
if (paramsMatcher2.find() && paramsMatcher2.groupCount() > 0) {
OAtokenSecret = paramsMatcher2.group(1);
}
@@ -244,7 +242,7 @@ public abstract class OAuthAuthorizationActivity extends AbstractActivity {
setTokens(OAtoken, OAtokenSecret, true);
status = AUTHENTICATED;
}
- } catch (Exception e) {
+ } catch (final Exception e) {
Log.e("OAuthAuthorizationActivity.changeToken", e);
}
@@ -258,7 +256,7 @@ public abstract class OAuthAuthorizationActivity extends AbstractActivity {
private class StartListener implements View.OnClickListener {
@Override
- public void onClick(View arg0) {
+ public void onClick(final View arg0) {
if (requestTokenDialog == null) {
requestTokenDialog = new ProgressDialog(OAuthAuthorizationActivity.this);
requestTokenDialog.setCancelable(false);
@@ -333,7 +331,7 @@ public abstract class OAuthAuthorizationActivity extends AbstractActivity {
* @return String with a more detailed error message (user-facing, localized), can be empty
*/
@SuppressWarnings("static-method")
- protected String getExtendedErrorMsg(HttpResponse response) {
+ protected String getExtendedErrorMsg(final HttpResponse response) {
return StringUtils.EMPTY;
}
@@ -363,14 +361,14 @@ public abstract class OAuthAuthorizationActivity extends AbstractActivity {
@NonNull public final String consumerSecret;
@NonNull public final String callback;
- public OAuthParameters(@NonNull String host,
- @NonNull String pathRequest,
- @NonNull String pathAuthorize,
- @NonNull String pathAccess,
- boolean https,
- @NonNull String consumerKey,
- @NonNull String consumerSecret,
- @NonNull String callback) {
+ public OAuthParameters(@NonNull final String host,
+ @NonNull final String pathRequest,
+ @NonNull final String pathAuthorize,
+ @NonNull final String pathAccess,
+ final boolean https,
+ @NonNull final String consumerKey,
+ @NonNull final String consumerSecret,
+ @NonNull final String callback) {
this.host = host;
this.pathRequest = pathRequest;
this.pathAuthorize = pathAuthorize;
@@ -381,7 +379,7 @@ public abstract class OAuthAuthorizationActivity extends AbstractActivity {
this.callback = callback;
}
- public void setOAuthExtras(Intent intent) {
+ public void setOAuthExtras(final Intent intent) {
if (intent != null) {
intent.putExtra(Intents.EXTRA_OAUTH_HOST, host);
intent.putExtra(Intents.EXTRA_OAUTH_PATH_REQUEST, pathRequest);
diff --git a/main/src/cgeo/geocaching/network/OAuthTokens.java b/main/src/cgeo/geocaching/network/OAuthTokens.java
new file mode 100644
index 0000000..9f45e7f
--- /dev/null
+++ b/main/src/cgeo/geocaching/network/OAuthTokens.java
@@ -0,0 +1,38 @@
+package cgeo.geocaching.network;
+
+import cgeo.geocaching.connector.oc.OCApiConnector;
+import cgeo.geocaching.settings.Settings;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.eclipse.jdt.annotation.NonNull;
+
+import android.util.Pair;
+
+public class OAuthTokens extends Pair<String, String> {
+
+ public OAuthTokens(@NonNull final OCApiConnector connector) {
+ this(Settings.getTokenPair(connector.getTokenPublicPrefKeyId(), connector.getTokenSecretPrefKeyId()));
+ }
+
+ public OAuthTokens(final ImmutablePair<String, String> tokenPair) {
+ this(tokenPair.left, tokenPair.right);
+ }
+
+ public OAuthTokens(final String pub, final String secret) {
+ super(pub, secret);
+ }
+
+ public boolean isValid() {
+ return StringUtils.isNotBlank(getTokenPublic()) && StringUtils.isNotBlank(getTokenSecret());
+ }
+
+ public String getTokenPublic() {
+ return first;
+ }
+
+ public String getTokenSecret() {
+ return second;
+ }
+
+}
diff --git a/main/src/cgeo/geocaching/network/SmileyImage.java b/main/src/cgeo/geocaching/network/SmileyImage.java
new file mode 100644
index 0000000..ebac2bb
--- /dev/null
+++ b/main/src/cgeo/geocaching/network/SmileyImage.java
@@ -0,0 +1,34 @@
+package cgeo.geocaching.network;
+
+import cgeo.geocaching.list.StoredList;
+
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.tuple.Pair;
+
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
+import android.widget.TextView;
+
+public class SmileyImage extends HtmlImage {
+
+ public SmileyImage(final String geocode, final TextView view) {
+ super(geocode, false, StoredList.STANDARD_LIST_ID, false, view);
+ }
+
+ @Override
+ protected Pair<BitmapDrawable, Boolean> scaleImage(final Pair<Bitmap, Boolean> loadResult) {
+ final Bitmap bitmap = loadResult.getLeft();
+ BitmapDrawable drawable;
+ if (bitmap != null) {
+ final int lineHeight = (int) (view.getLineHeight() * 0.8);
+ drawable = new BitmapDrawable(view.getResources(), bitmap);
+ final int width = drawable.getIntrinsicWidth() * lineHeight / drawable.getIntrinsicHeight();
+ drawable.setBounds(0, 0, width, lineHeight);
+ }
+ else {
+ drawable = null;
+ }
+ return new ImmutablePair<>(drawable, loadResult.getRight());
+ }
+
+}
diff --git a/main/src/cgeo/geocaching/network/StatusUpdater.java b/main/src/cgeo/geocaching/network/StatusUpdater.java
index 82650d1..bc4a5db 100644
--- a/main/src/cgeo/geocaching/network/StatusUpdater.java
+++ b/main/src/cgeo/geocaching/network/StatusUpdater.java
@@ -4,8 +4,7 @@ import cgeo.geocaching.CgeoApplication;
import cgeo.geocaching.utils.RxUtils;
import cgeo.geocaching.utils.Version;
-import org.json.JSONException;
-import org.json.JSONObject;
+import com.fasterxml.jackson.databind.node.ObjectNode;
import rx.functions.Action0;
import rx.subjects.BehaviorSubject;
@@ -31,11 +30,11 @@ public class StatusUpdater {
this.url = url;
}
- Status(final JSONObject response) {
- message = get(response, "message");
- messageId = get(response, "message_id");
- icon = get(response, "icon");
- url = get(response, "url");
+ Status(final ObjectNode response) {
+ message = response.path("message").asText(null);
+ messageId = response.path("message_id").asText(null);
+ icon = response.path("icon").asText(null);
+ url = response.path("url").asText(null);
}
final static public Status closeoutStatus =
@@ -55,7 +54,7 @@ public class StatusUpdater {
RxUtils.networkScheduler.createWorker().schedulePeriodically(new Action0() {
@Override
public void call() {
- final JSONObject response =
+ final ObjectNode response =
Network.requestJSON("http://status.cgeo.org/api/status.json",
new Parameters("version_code", String.valueOf(Version.getVersionCode(CgeoApplication.getInstance())),
"version_name", Version.getVersionName(CgeoApplication.getInstance()),
@@ -67,12 +66,4 @@ public class StatusUpdater {
}, 0, 1800, TimeUnit.SECONDS);
}
- private static String get(final JSONObject json, final String key) {
- try {
- return json.getString(key);
- } catch (final JSONException e) {
- return null;
- }
- }
-
}
diff --git a/main/src/cgeo/geocaching/sensors/GeoData.java b/main/src/cgeo/geocaching/sensors/GeoData.java
index c0b3974..2061b6b 100644
--- a/main/src/cgeo/geocaching/sensors/GeoData.java
+++ b/main/src/cgeo/geocaching/sensors/GeoData.java
@@ -7,17 +7,9 @@ import android.location.Location;
import android.location.LocationManager;
class GeoData extends Location implements IGeoData {
- private final boolean gpsEnabled;
- private final int satellitesVisible;
- private final int satellitesFixed;
- private final boolean pseudoLocation;
- GeoData(final Location location, final boolean gpsEnabled, final int satellitesVisible, final int satellitesFixed, final boolean pseudoLocation) {
+ GeoData(final Location location) {
super(location);
- this.gpsEnabled = gpsEnabled;
- this.satellitesVisible = satellitesVisible;
- this.satellitesFixed = satellitesFixed;
- this.pseudoLocation = pseudoLocation;
}
@Override
@@ -44,24 +36,4 @@ class GeoData extends Location implements IGeoData {
public Geopoint getCoords() {
return new Geopoint(this);
}
-
- @Override
- public boolean getGpsEnabled() {
- return gpsEnabled;
- }
-
- @Override
- public int getSatellitesVisible() {
- return satellitesVisible;
- }
-
- @Override
- public int getSatellitesFixed() {
- return satellitesFixed;
- }
-
- @Override
- public boolean isPseudoLocation() {
- return pseudoLocation;
- }
}
diff --git a/main/src/cgeo/geocaching/sensors/GeoDataProvider.java b/main/src/cgeo/geocaching/sensors/GeoDataProvider.java
index a4799cb..7645d7f 100644
--- a/main/src/cgeo/geocaching/sensors/GeoDataProvider.java
+++ b/main/src/cgeo/geocaching/sensors/GeoDataProvider.java
@@ -1,25 +1,15 @@
package cgeo.geocaching.sensors;
import cgeo.geocaching.utils.Log;
-import cgeo.geocaching.utils.StartableHandlerThread;
-
-import org.apache.commons.lang3.StringUtils;
+import cgeo.geocaching.utils.RxUtils.ConnectableLooperCallbacks;
import rx.Observable;
import rx.Observable.OnSubscribe;
import rx.Subscriber;
-import rx.Subscription;
-import rx.android.schedulers.AndroidSchedulers;
-import rx.functions.Action0;
-import rx.functions.Action1;
import rx.observables.ConnectableObservable;
import rx.subjects.BehaviorSubject;
-import rx.subscriptions.CompositeSubscription;
-import rx.subscriptions.Subscriptions;
import android.content.Context;
-import android.location.GpsSatellite;
-import android.location.GpsStatus;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
@@ -29,20 +19,10 @@ import java.util.concurrent.TimeUnit;
public class GeoDataProvider implements OnSubscribe<IGeoData> {
- private static final String LAST_LOCATION_PSEUDO_PROVIDER = "last";
private final LocationManager geoManager;
private final LocationData gpsLocation = new LocationData();
private final LocationData netLocation = new LocationData();
private final BehaviorSubject<IGeoData> subject;
- private static final StartableHandlerThread handlerThread =
- new StartableHandlerThread("GeoDataProvider thread", android.os.Process.THREAD_PRIORITY_BACKGROUND);
- static {
- handlerThread.start();
- }
-
- public boolean gpsEnabled = false;
- public int satellitesVisible = 0;
- public int satellitesFixed = 0;
private static class LocationData {
public Location location;
@@ -85,62 +65,32 @@ public class GeoDataProvider implements OnSubscribe<IGeoData> {
subject.subscribe(subscriber);
}
- final ConnectableObservable<IGeoData> worker = new ConnectableObservable<IGeoData>(this) {
- private int debugSessionCounter = 0;
-
- private final Object lock = new Object();
- private int count = 0;
-
- final private GpsStatus.Listener gpsStatusListener = new GpsStatusListener();
- final private Listener networkListener = new Listener(LocationManager.NETWORK_PROVIDER, netLocation);
- final private Listener gpsListener = new Listener(LocationManager.GPS_PROVIDER, gpsLocation);
+ final ConnectableObservable<IGeoData> worker = new ConnectableLooperCallbacks<IGeoData>(this, 2500, TimeUnit.MILLISECONDS) {
+ private final Listener networkListener = new Listener(LocationManager.NETWORK_PROVIDER, netLocation);
+ private final Listener gpsListener = new Listener(LocationManager.GPS_PROVIDER, gpsLocation);
@Override
- public void connect(Action1<? super Subscription> connection) {
- final CompositeSubscription subscription = new CompositeSubscription();
- AndroidSchedulers.handlerThread(handlerThread.getHandler()).createWorker().schedule(new Action0() {
- @Override
- public void call() {
- synchronized(lock) {
- if (count++ == 0) {
- Log.d("GeoDataProvider: starting the GPS and network listeners" + " (" + ++debugSessionCounter + ")");
- geoManager.addGpsStatusListener(gpsStatusListener);
- for (final Listener listener : new Listener[] { networkListener, gpsListener }) {
- try {
- geoManager.requestLocationUpdates(listener.locationProvider, 0, 0, listener);
- } catch (final Exception e) {
- Log.w("There is no location provider " + listener.locationProvider);
- }
- }
- }
- }
-
- subscription.add(Subscriptions.create(new Action0() {
- @Override
- public void call() {
- AndroidSchedulers.handlerThread(handlerThread.getHandler()).createWorker().schedule(new Action0() {
- @Override
- public void call() {
- synchronized (lock) {
- if (--count == 0) {
- Log.d("GeoDataProvider: stopping the GPS and network listeners" + " (" + debugSessionCounter + ")");
- geoManager.removeUpdates(networkListener);
- geoManager.removeUpdates(gpsListener);
- geoManager.removeGpsStatusListener(gpsStatusListener);
- }
- }
- }
- }, 2500, TimeUnit.MILLISECONDS);
- }
- }));
+ protected void onStart() {
+ Log.d("GeoDataProvider: starting the GPS and network listeners");
+ for (final Listener listener : new Listener[]{networkListener, gpsListener}) {
+ try {
+ geoManager.requestLocationUpdates(listener.locationProvider, 0, 0, listener);
+ } catch (final Exception e) {
+ Log.w("There is no location provider " + listener.locationProvider);
}
- });
- connection.call(subscription);
+ }
+ }
+
+ @Override
+ protected void onStop() {
+ Log.d("GeoDataProvider: stopping the GPS and network listeners");
+ geoManager.removeUpdates(networkListener);
+ geoManager.removeUpdates(gpsListener);
}
};
private IGeoData findInitialLocation() {
- final Location initialLocation = new Location(LAST_LOCATION_PSEUDO_PROVIDER);
+ final Location initialLocation = new Location("initial");
try {
// Try to find a sensible initial location from the last locations known to Android.
final Location lastGpsLocation = geoManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
@@ -167,7 +117,7 @@ public class GeoDataProvider implements OnSubscribe<IGeoData> {
}
// Start with an historical GeoData just in case someone queries it before we get
// a chance to get any information.
- return new GeoData(initialLocation, false, 0, 0, true);
+ return new GeoData(initialLocation);
}
private static void copyCoords(final Location target, final Location source) {
@@ -206,54 +156,6 @@ public class GeoDataProvider implements OnSubscribe<IGeoData> {
}
}
- private final class GpsStatusListener implements GpsStatus.Listener {
-
- @Override
- public void onGpsStatusChanged(final int event) {
- boolean changed = false;
- switch (event) {
- case GpsStatus.GPS_EVENT_FIRST_FIX:
- case GpsStatus.GPS_EVENT_SATELLITE_STATUS: {
- final GpsStatus status = geoManager.getGpsStatus(null);
- int visible = 0;
- int fixed = 0;
- for (final GpsSatellite satellite : status.getSatellites()) {
- if (satellite.usedInFix()) {
- fixed++;
- }
- visible++;
- }
- if (visible != satellitesVisible || fixed != satellitesFixed) {
- satellitesVisible = visible;
- satellitesFixed = fixed;
- changed = true;
- }
- break;
- }
- case GpsStatus.GPS_EVENT_STARTED:
- if (!gpsEnabled) {
- gpsEnabled = true;
- changed = true;
- }
- break;
- case GpsStatus.GPS_EVENT_STOPPED:
- if (gpsEnabled) {
- gpsEnabled = false;
- satellitesFixed = 0;
- satellitesVisible = 0;
- changed = true;
- }
- break;
- default:
- throw new IllegalStateException();
- }
-
- if (changed) {
- selectBest();
- }
- }
- }
-
private LocationData best() {
if (gpsLocation.isRecent() || !netLocation.isValid()) {
return gpsLocation.isValid() ? gpsLocation : null;
@@ -274,9 +176,7 @@ public class GeoDataProvider implements OnSubscribe<IGeoData> {
}
// We do not necessarily get signalled when satellites go to 0/0.
- final int visible = gpsLocation.isRecent() ? satellitesVisible : 0;
- final boolean pseudoLocation = StringUtils.equals(locationData.location.getProvider(), LAST_LOCATION_PSEUDO_PROVIDER);
- final IGeoData current = new GeoData(locationData.location, gpsEnabled, visible, satellitesFixed, pseudoLocation);
+ final IGeoData current = new GeoData(locationData.location);
subject.onNext(current);
}
diff --git a/main/src/cgeo/geocaching/sensors/GpsStatusProvider.java b/main/src/cgeo/geocaching/sensors/GpsStatusProvider.java
new file mode 100644
index 0000000..61243c3
--- /dev/null
+++ b/main/src/cgeo/geocaching/sensors/GpsStatusProvider.java
@@ -0,0 +1,112 @@
+package cgeo.geocaching.sensors;
+
+import cgeo.geocaching.sensors.GpsStatusProvider.Status;
+import cgeo.geocaching.utils.Log;
+import cgeo.geocaching.utils.RxUtils.ConnectableLooperCallbacks;
+
+import rx.Observable;
+import rx.Observable.OnSubscribe;
+import rx.Subscriber;
+import rx.observables.ConnectableObservable;
+import rx.subjects.BehaviorSubject;
+
+import android.content.Context;
+import android.location.GpsSatellite;
+import android.location.GpsStatus;
+import android.location.LocationManager;
+
+public class GpsStatusProvider implements OnSubscribe<Status> {
+
+ public static class Status {
+ final public boolean gpsEnabled;
+ final public int satellitesVisible;
+ final public int satellitesFixed;
+
+ public Status(final boolean gpsEnabled, final int satellitesVisible, final int satellitesFixed) {
+ this.gpsEnabled = gpsEnabled;
+ this.satellitesVisible = satellitesVisible;
+ this.satellitesFixed = satellitesFixed;
+ }
+ }
+
+ private final LocationManager geoManager;
+ private final BehaviorSubject<Status> subject;
+
+ private Status latest = new Status(false, 0, 0);
+
+ /**
+ * Build a new gps status provider object.
+ * <p/>
+ * There is no need to instantiate more than one such object in an application, as observers can be added
+ * at will.
+ *
+ * @param context the context used to retrieve the system services
+ */
+ protected GpsStatusProvider(final Context context) {
+ geoManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
+ subject = BehaviorSubject.create(latest);
+ }
+
+ public static Observable<Status> create(final Context context) {
+ final GpsStatusProvider provider = new GpsStatusProvider(context);
+ return provider.worker.refCount();
+ }
+
+ @Override
+ public void call(final Subscriber<? super Status> subscriber) {
+ subject.subscribe(subscriber);
+ }
+
+ final ConnectableObservable<Status> worker = new ConnectableLooperCallbacks<Status>(this) {
+ private final GpsStatus.Listener gpsStatusListener = new GpsStatusListener();
+
+ @Override
+ protected void onStart() {
+ Log.d("GpsStatusProvider: starting the GPS status listener");
+ geoManager.addGpsStatusListener(gpsStatusListener);
+ }
+
+ @Override
+ protected void onStop() {
+ Log.d("GpsStatusProvider: stopping the GPS status listener");
+ geoManager.removeGpsStatusListener(gpsStatusListener);
+ }
+ };
+
+ private final class GpsStatusListener implements GpsStatus.Listener {
+
+ @Override
+ public void onGpsStatusChanged(final int event) {
+ switch (event) {
+ case GpsStatus.GPS_EVENT_FIRST_FIX:
+ case GpsStatus.GPS_EVENT_SATELLITE_STATUS: {
+ final GpsStatus status = geoManager.getGpsStatus(null);
+ int visible = 0;
+ int fixed = 0;
+ for (final GpsSatellite satellite : status.getSatellites()) {
+ if (satellite.usedInFix()) {
+ fixed++;
+ }
+ visible++;
+ }
+ if (visible == latest.satellitesVisible && fixed == latest.satellitesFixed) {
+ return;
+ }
+ latest = new Status(true, visible, fixed);
+ break;
+ }
+ case GpsStatus.GPS_EVENT_STARTED:
+ latest = new Status(true, 0, 0);
+ break;
+ case GpsStatus.GPS_EVENT_STOPPED:
+ latest = new Status(false, 0, 0);
+ break;
+ default:
+ throw new IllegalStateException();
+ }
+
+ subject.onNext(latest);
+ }
+ }
+
+}
diff --git a/main/src/cgeo/geocaching/sensors/IGeoData.java b/main/src/cgeo/geocaching/sensors/IGeoData.java
index 5b4f046..b78b805 100644
--- a/main/src/cgeo/geocaching/sensors/IGeoData.java
+++ b/main/src/cgeo/geocaching/sensors/IGeoData.java
@@ -10,13 +10,8 @@ public interface IGeoData {
public Location getLocation();
public LocationProviderType getLocationProvider();
- public boolean isPseudoLocation();
-
public Geopoint getCoords();
public float getBearing();
public float getSpeed();
public float getAccuracy();
- public boolean getGpsEnabled();
- public int getSatellitesVisible();
- public int getSatellitesFixed();
}
diff --git a/main/src/cgeo/geocaching/settings/Settings.java b/main/src/cgeo/geocaching/settings/Settings.java
index 01ebd6f..b1c5c31 100644
--- a/main/src/cgeo/geocaching/settings/Settings.java
+++ b/main/src/cgeo/geocaching/settings/Settings.java
@@ -154,7 +154,6 @@ public class Settings {
e.putInt(getKey(R.string.pref_defaultNavigationTool2), old.getInt(getKey(R.string.pref_defaultNavigationTool2), NavigationAppsEnum.INTERNAL_MAP.id));
e.putInt(getKey(R.string.pref_livemapstrategy), old.getInt(getKey(R.string.pref_livemapstrategy), Strategy.AUTO.id));
e.putBoolean(getKey(R.string.pref_debug), old.getBoolean(getKey(R.string.pref_debug), false));
- e.putBoolean(getKey(R.string.pref_hidelivemaphint), old.getInt(getKey(R.string.pref_hidelivemaphint), 0) != 0);
e.putInt(getKey(R.string.pref_livemaphintshowcount), old.getInt(getKey(R.string.pref_livemaphintshowcount), 0));
e.putInt(getKey(R.string.pref_settingsversion), 1); // mark migrated
@@ -612,7 +611,7 @@ public class Settings {
mapSource = MapProviderFactory.getMapSource(id);
if (mapSource != null) {
// don't use offline maps if the map file is not valid
- if ((!(mapSource instanceof OfflineMapSource)) || (isValidMapFile())) {
+ if (!(mapSource instanceof OfflineMapSource) || isValidMapFile()) {
return mapSource;
}
}
@@ -835,14 +834,6 @@ public class Settings {
return Log.isDebug();
}
- public static boolean getHideLiveMapHint() {
- return getBoolean(R.string.pref_hidelivemaphint, false);
- }
-
- public static void setHideLiveHint(final boolean hide) {
- putBoolean(R.string.pref_hidelivemaphint, hide);
- }
-
public static int getLiveMapHintShowCount() {
return getInt(R.string.pref_livemaphintshowcount, 0);
}
diff --git a/main/src/cgeo/geocaching/sorting/PopularityRatioComparator.java b/main/src/cgeo/geocaching/sorting/PopularityRatioComparator.java
index 57a69ee..a2da6ee 100644
--- a/main/src/cgeo/geocaching/sorting/PopularityRatioComparator.java
+++ b/main/src/cgeo/geocaching/sorting/PopularityRatioComparator.java
@@ -26,7 +26,8 @@ public class PopularityRatioComparator extends AbstractCacheComparator {
if ((ratio2 - ratio1) > 0.0f) {
return 1;
- } else if ((ratio2 - ratio1) < 0.0f) {
+ }
+ if ((ratio2 - ratio1) < 0.0f) {
return -1;
}
diff --git a/main/src/cgeo/geocaching/sorting/SortActionProvider.java b/main/src/cgeo/geocaching/sorting/SortActionProvider.java
index e9e65a0..61b2ffb 100644
--- a/main/src/cgeo/geocaching/sorting/SortActionProvider.java
+++ b/main/src/cgeo/geocaching/sorting/SortActionProvider.java
@@ -136,9 +136,7 @@ public class SortActionProvider extends ActionProvider implements OnMenuItemClic
final CacheComparator comparator = cacheComparator.newInstance();
onClickListener.call(comparator);
}
- } catch (final InstantiationException e) {
- Log.e("selectComparator", e);
- } catch (final IllegalAccessException e) {
+ } catch (final InstantiationException | IllegalAccessException e) {
Log.e("selectComparator", e);
}
}
diff --git a/main/src/cgeo/geocaching/twitter/Twitter.java b/main/src/cgeo/geocaching/twitter/Twitter.java
index c89c0b6..253d91f 100644
--- a/main/src/cgeo/geocaching/twitter/Twitter.java
+++ b/main/src/cgeo/geocaching/twitter/Twitter.java
@@ -10,6 +10,7 @@ import cgeo.geocaching.geopoint.Geopoint;
import cgeo.geocaching.geopoint.GeopointFormatter.Format;
import cgeo.geocaching.network.Network;
import cgeo.geocaching.network.OAuth;
+import cgeo.geocaching.network.OAuthTokens;
import cgeo.geocaching.network.Parameters;
import cgeo.geocaching.settings.Settings;
import cgeo.geocaching.utils.Log;
@@ -17,6 +18,7 @@ import cgeo.geocaching.utils.LogTemplateProvider;
import cgeo.geocaching.utils.LogTemplateProvider.LogContext;
import ch.boye.httpclientandroidlib.HttpResponse;
+
import org.apache.commons.lang3.StringUtils;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
@@ -25,7 +27,7 @@ public final class Twitter {
private static final String HASH_PREFIX_WITH_BLANK = " #";
private static final int MAX_TWEET_SIZE = 140;
- public static void postTweetCache(String geocode, final @Nullable LogEntry logEntry) {
+ public static void postTweetCache(final String geocode, final @Nullable LogEntry logEntry) {
final Geocache cache = DataStore.loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB);
if (cache == null) {
return;
@@ -33,7 +35,7 @@ public final class Twitter {
postTweet(CgeoApplication.getInstance(), getStatusMessage(cache, logEntry), null);
}
- public static void postTweetTrackable(String geocode, final @Nullable LogEntry logEntry) {
+ public static void postTweetTrackable(final String geocode, final @Nullable LogEntry logEntry) {
final Trackable trackable = DataStore.loadTrackable(geocode);
if (trackable == null) {
return;
@@ -48,7 +50,7 @@ public final class Twitter {
try {
final String status = shortenToMaxSize(statusIn);
- Parameters parameters = new Parameters("status", status);
+ final Parameters parameters = new Parameters("status", status);
if (coords != null) {
parameters.put(
"lat", coords.format(Format.LAT_DECDEGREE_RAW),
@@ -56,7 +58,7 @@ public final class Twitter {
"display_coordinates", "true");
}
- OAuth.signOAuth("api.twitter.com", "/1.1/statuses/update.json", "POST", true, parameters, Settings.getTokenPublic(), Settings.getTokenSecret(), Settings.getKeyConsumerPublic(), Settings.getKeyConsumerSecret());
+ OAuth.signOAuth("api.twitter.com", "/1.1/statuses/update.json", "POST", true, parameters, new OAuthTokens(Settings.getTokenPublic(), Settings.getTokenSecret()), Settings.getKeyConsumerPublic(), Settings.getKeyConsumerSecret());
final HttpResponse httpResponse = Network.postRequest("https://api.twitter.com/1.1/statuses/update.json", parameters);
if (httpResponse != null) {
if (httpResponse.getStatusLine().getStatusCode() == 200) {
@@ -67,13 +69,13 @@ public final class Twitter {
} else {
Log.e("Tweet could not be posted. Reason: httpResponse Object is null");
}
- } catch (Exception e) {
+ } catch (final Exception e) {
Log.e("Twitter.postTweet", e);
}
}
private static String shortenToMaxSize(final String status) {
- String result = StringUtils.trim(status);
+ final String result = StringUtils.trim(status);
if (StringUtils.length(result) > MAX_TWEET_SIZE) {
return StringUtils.substring(result, 0, MAX_TWEET_SIZE - 1) + '…';
}
@@ -98,7 +100,7 @@ public final class Twitter {
}
private static String appendHashTags(final String status) {
- StringBuilder builder = new StringBuilder(status);
+ final StringBuilder builder = new StringBuilder(status);
appendHashTag(builder, "cgeo");
appendHashTag(builder, "geocaching");
return builder.toString();
diff --git a/main/src/cgeo/geocaching/ui/DecryptTextClickListener.java b/main/src/cgeo/geocaching/ui/DecryptTextClickListener.java
index e2e587e..3af950f 100644
--- a/main/src/cgeo/geocaching/ui/DecryptTextClickListener.java
+++ b/main/src/cgeo/geocaching/ui/DecryptTextClickListener.java
@@ -1,40 +1,37 @@
-package cgeo.geocaching.ui;
-
-import cgeo.geocaching.utils.CryptUtils;
-
-import org.eclipse.jdt.annotation.NonNull;
-
-import android.text.Spannable;
-import android.view.View;
-import android.widget.TextView;
-
-public class DecryptTextClickListener implements View.OnClickListener {
-
- @NonNull private final TextView targetView;
-
- public DecryptTextClickListener(@NonNull final TextView targetView) {
- this.targetView = targetView;
- }
-
- @Override
- public final void onClick(final View view) {
- try {
- // do not run the click listener if a link was clicked
- if (targetView.getSelectionStart() != -1 || targetView.getSelectionEnd() != -1) {
- return;
- }
-
- CharSequence text = targetView.getText();
- if (text instanceof Spannable) {
- Spannable span = (Spannable) text;
- targetView.setText(CryptUtils.rot13(span));
- }
- else {
- String string = (String) text;
- targetView.setText(CryptUtils.rot13(string));
- }
- } catch (RuntimeException e) {
- // nothing
- }
- }
-}
+package cgeo.geocaching.ui;
+
+import cgeo.geocaching.utils.CryptUtils;
+
+import org.eclipse.jdt.annotation.NonNull;
+
+import android.text.Spannable;
+import android.view.View;
+import android.widget.TextView;
+
+public class DecryptTextClickListener implements View.OnClickListener {
+
+ @NonNull private final TextView targetView;
+
+ public DecryptTextClickListener(@NonNull final TextView targetView) {
+ this.targetView = targetView;
+ }
+
+ @Override
+ public final void onClick(final View view) {
+ try {
+ // do not run the click listener if a link was clicked
+ if (targetView.getSelectionStart() != -1 || targetView.getSelectionEnd() != -1) {
+ return;
+ }
+
+ CharSequence text = targetView.getText();
+ if (text instanceof Spannable) {
+ targetView.setText(CryptUtils.rot13((Spannable) text));
+ } else {
+ targetView.setText(CryptUtils.rot13((String) text));
+ }
+ } catch (final RuntimeException ignore) {
+ // nothing
+ }
+ }
+}
diff --git a/main/src/cgeo/geocaching/ui/ImagesList.java b/main/src/cgeo/geocaching/ui/ImagesList.java
index 8bd4ac2..458f8db 100644
--- a/main/src/cgeo/geocaching/ui/ImagesList.java
+++ b/main/src/cgeo/geocaching/ui/ImagesList.java
@@ -102,7 +102,7 @@ public class ImagesList {
imagesView = ButterKnife.findById(parentView, R.id.spoiler_list);
- final HtmlImage imgGetter = new HtmlImage(geocode, true, offline ? StoredList.STANDARD_LIST_ID : StoredList.TEMPORARY_LIST_ID, false);
+ final HtmlImage imgGetter = new HtmlImage(geocode, true, offline ? StoredList.STANDARD_LIST_ID : StoredList.TEMPORARY_LIST.id, false);
for (final Image img : images) {
final LinearLayout rowView = (LinearLayout) inflater.inflate(R.layout.cache_image_item, imagesView, false);
diff --git a/main/src/cgeo/geocaching/ui/dialog/DateDialog.java b/main/src/cgeo/geocaching/ui/dialog/DateDialog.java
index 1046f81..15c9556 100644
--- a/main/src/cgeo/geocaching/ui/dialog/DateDialog.java
+++ b/main/src/cgeo/geocaching/ui/dialog/DateDialog.java
@@ -22,11 +22,11 @@ public class DateDialog extends DialogFragment {
private Calendar date;
public static DateDialog getInstance(final Calendar date) {
- final DateDialog dd = new DateDialog();
+ final DateDialog dateDialog = new DateDialog();
final Bundle args = new Bundle();
args.putSerializable("date", date);
- dd.setArguments(args);
- return dd;
+ dateDialog.setArguments(args);
+ return dateDialog;
}
@Override
diff --git a/main/src/cgeo/geocaching/ui/logs/LogsViewCreator.java b/main/src/cgeo/geocaching/ui/logs/LogsViewCreator.java
index 23caf79..3aaeec1 100644
--- a/main/src/cgeo/geocaching/ui/logs/LogsViewCreator.java
+++ b/main/src/cgeo/geocaching/ui/logs/LogsViewCreator.java
@@ -4,8 +4,7 @@ import cgeo.geocaching.ImagesActivity;
import cgeo.geocaching.LogEntry;
import cgeo.geocaching.R;
import cgeo.geocaching.activity.AbstractActionBarActivity;
-import cgeo.geocaching.list.StoredList;
-import cgeo.geocaching.network.HtmlImage;
+import cgeo.geocaching.network.SmileyImage;
import cgeo.geocaching.ui.AbstractCachingListViewPageViewCreator;
import cgeo.geocaching.ui.AnchorAwareLinkMovementMethod;
import cgeo.geocaching.ui.DecryptTextClickListener;
@@ -87,7 +86,7 @@ public abstract class LogsViewCreator extends AbstractCachingListViewPageViewCre
if (TextUtils.containsHtml(logText)) {
logText = log.getDisplayText();
final UnknownTagsHandler unknownTagsHandler = new UnknownTagsHandler();
- holder.text.setText(Html.fromHtml(logText, new HtmlImage(getGeocode(), false, StoredList.STANDARD_LIST_ID, false, holder.text),
+ holder.text.setText(Html.fromHtml(logText, new SmileyImage(getGeocode(), holder.text),
unknownTagsHandler), TextView.BufferType.SPANNABLE);
} else {
holder.text.setText(logText, TextView.BufferType.SPANNABLE);
diff --git a/main/src/cgeo/geocaching/utils/CryptUtils.java b/main/src/cgeo/geocaching/utils/CryptUtils.java
index 815c2f4..f2ff0c2 100644
--- a/main/src/cgeo/geocaching/utils/CryptUtils.java
+++ b/main/src/cgeo/geocaching/utils/CryptUtils.java
@@ -1,6 +1,5 @@
package cgeo.geocaching.utils;
-
import org.apache.commons.lang3.CharEncoding;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.jdt.annotation.NonNull;
@@ -23,28 +22,29 @@ public final class CryptUtils {
// utility class
}
- private static char[] base64map1 = new char[64];
- private static byte[] base64map2 = new byte[128];
+ private static final byte[] EMPTY = {};
+ private static char[] BASE64MAP1 = new char[64];
+ private static byte[] BASE64MAP2 = new byte[128];
static {
int i = 0;
for (char c = 'A'; c <= 'Z'; c++) {
- base64map1[i++] = c;
+ BASE64MAP1[i++] = c;
}
for (char c = 'a'; c <= 'z'; c++) {
- base64map1[i++] = c;
+ BASE64MAP1[i++] = c;
}
for (char c = '0'; c <= '9'; c++) {
- base64map1[i++] = c;
+ BASE64MAP1[i++] = c;
}
- base64map1[i++] = '+';
- base64map1[i++] = '/';
+ BASE64MAP1[i++] = '+';
+ BASE64MAP1[i++] = '/';
- for (i = 0; i < base64map2.length; i++) {
- base64map2[i] = -1;
+ for (i = 0; i < BASE64MAP2.length; i++) {
+ BASE64MAP2[i] = -1;
}
for (i = 0; i < 64; i++) {
- base64map2[base64map1[i]] = (byte) i;
+ BASE64MAP2[BASE64MAP1[i]] = (byte) i;
}
}
@@ -88,9 +88,7 @@ public final class CryptUtils {
final MessageDigest digest = MessageDigest.getInstance("MD5");
digest.update(text.getBytes(CharEncoding.UTF_8), 0, text.length());
return new BigInteger(1, digest.digest()).toString(16);
- } catch (NoSuchAlgorithmException e) {
- Log.e("CryptUtils.md5", e);
- } catch (UnsupportedEncodingException e) {
+ } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
Log.e("CryptUtils.md5", e);
}
@@ -98,20 +96,16 @@ public final class CryptUtils {
}
public static byte[] hashHmac(String text, String salt) {
- byte[] macBytes = {};
try {
final SecretKeySpec secretKeySpec = new SecretKeySpec(salt.getBytes(CharEncoding.UTF_8), "HmacSHA1");
final Mac mac = Mac.getInstance("HmacSHA1");
mac.init(secretKeySpec);
- macBytes = mac.doFinal(text.getBytes(CharEncoding.UTF_8));
- } catch (GeneralSecurityException e) {
- Log.e("CryptUtils.hashHmac", e);
- } catch (UnsupportedEncodingException e) {
+ return mac.doFinal(text.getBytes(CharEncoding.UTF_8));
+ } catch (GeneralSecurityException | UnsupportedEncodingException e) {
Log.e("CryptUtils.hashHmac", e);
+ return EMPTY;
}
-
- return macBytes;
}
public static CharSequence rot13(final Spannable span) {
@@ -145,11 +139,11 @@ public final class CryptUtils {
int o1 = ((i0 & 3) << 4) | (i1 >>> 4);
int o2 = ((i1 & 0xf) << 2) | (i2 >>> 6);
int o3 = i2 & 0x3F;
- out[op++] = base64map1[o0];
- out[op++] = base64map1[o1];
- out[op] = op < oDataLen ? base64map1[o2] : '=';
+ out[op++] = BASE64MAP1[o0];
+ out[op++] = BASE64MAP1[o1];
+ out[op] = op < oDataLen ? BASE64MAP1[o2] : '=';
op++;
- out[op] = op < oDataLen ? base64map1[o3] : '=';
+ out[op] = op < oDataLen ? BASE64MAP1[o3] : '=';
op++;
}
diff --git a/main/src/cgeo/geocaching/utils/JsonUtils.java b/main/src/cgeo/geocaching/utils/JsonUtils.java
new file mode 100644
index 0000000..492e137
--- /dev/null
+++ b/main/src/cgeo/geocaching/utils/JsonUtils.java
@@ -0,0 +1,20 @@
+package cgeo.geocaching.utils;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.ObjectReader;
+import com.fasterxml.jackson.databind.ObjectWriter;
+import com.fasterxml.jackson.databind.node.JsonNodeFactory;
+
+public class JsonUtils {
+
+ private static final ObjectMapper mapper = new ObjectMapper();
+ public static final ObjectReader reader = mapper.reader();
+ public static final ObjectWriter writer = mapper.writer();
+
+ public static final JsonNodeFactory factory = new JsonNodeFactory(true);
+
+ private JsonUtils() {
+ // Do not instantiate
+ }
+
+}
diff --git a/main/src/cgeo/geocaching/utils/LeastRecentlyUsedSet.java b/main/src/cgeo/geocaching/utils/LeastRecentlyUsedSet.java
index a69f427..d4cf16e 100644
--- a/main/src/cgeo/geocaching/utils/LeastRecentlyUsedSet.java
+++ b/main/src/cgeo/geocaching/utils/LeastRecentlyUsedSet.java
@@ -20,12 +20,9 @@ import java.util.List;
* access has to be guarded externally or the synchronized getAsList method can be used
* to get a clone for iteration.
*/
-public class LeastRecentlyUsedSet<E> extends AbstractSet<E>
- implements Cloneable, java.io.Serializable {
+public class LeastRecentlyUsedSet<E> extends AbstractSet<E> {
- private static final long serialVersionUID = -1942301031191419547L;
-
- private transient LeastRecentlyUsedMap<E, Object> map;
+ private final LeastRecentlyUsedMap<E, Object> map;
private static final Object PRESENT = new Object();
public LeastRecentlyUsedSet(int maxEntries, int initialCapacity, float loadFactor) {
@@ -132,26 +129,6 @@ public class LeastRecentlyUsedSet<E> extends AbstractSet<E>
}
/**
- * (synchronized) Clone of the set
- * Copy of the HashSet code if clone()
- *
- * @see HashSet
- */
- @Override
- @SuppressWarnings("unchecked")
- public Object clone() throws CloneNotSupportedException {
- try {
- synchronized (this) {
- final LeastRecentlyUsedSet<E> newSet = (LeastRecentlyUsedSet<E>) super.clone();
- newSet.map = (LeastRecentlyUsedMap<E, Object>) map.clone();
- return newSet;
- }
- } catch (CloneNotSupportedException e) {
- throw new InternalError();
- }
- }
-
- /**
* Creates a clone as a list in a synchronized fashion.
*
* @return List based clone of the set
@@ -160,56 +137,4 @@ public class LeastRecentlyUsedSet<E> extends AbstractSet<E>
return new ArrayList<>(this);
}
- /**
- * Serialization version of HashSet with the additional parameters for the custom Map
- *
- * @see HashSet
- */
- private void writeObject(java.io.ObjectOutputStream s)
- throws java.io.IOException {
- // Write out any hidden serialization magic
- s.defaultWriteObject();
-
- // Write out HashMap capacity and load factor
- s.writeInt(map.initialCapacity);
- s.writeFloat(map.loadFactor);
- s.writeInt(map.getMaxEntries());
-
- // Write out size
- s.writeInt(map.size());
-
- // Write out all elements in the proper order.
- for (final E e : map.keySet()) {
- s.writeObject(e);
- }
- }
-
- /**
- * Serialization version of HashSet with the additional parameters for the custom Map
- *
- * @see HashSet
- */
- @SuppressWarnings("unchecked")
- private void readObject(java.io.ObjectInputStream s)
- throws java.io.IOException, ClassNotFoundException {
- // Read in any hidden serialization magic
- s.defaultReadObject();
-
- // Read in HashMap capacity and load factor and create backing HashMap
- final int capacity = s.readInt();
- final float loadFactor = s.readFloat();
- final int maxEntries = s.readInt();
-
- map = new LeastRecentlyUsedMap.LruCache<>(maxEntries, capacity, loadFactor);
-
- // Read in size
- final int size = s.readInt();
-
- // Read in all elements in the proper order.
- for (int i = 0; i < size; i++) {
- E e = (E) s.readObject();
- map.put(e, PRESENT);
- }
- }
-
}
diff --git a/main/src/cgeo/geocaching/utils/OOMDumpingUncaughtExceptionHandler.java b/main/src/cgeo/geocaching/utils/OOMDumpingUncaughtExceptionHandler.java
index 1401542..0c6365c 100644
--- a/main/src/cgeo/geocaching/utils/OOMDumpingUncaughtExceptionHandler.java
+++ b/main/src/cgeo/geocaching/utils/OOMDumpingUncaughtExceptionHandler.java
@@ -11,14 +11,12 @@ public class OOMDumpingUncaughtExceptionHandler implements UncaughtExceptionHand
private boolean defaultReplaced = false;
public static boolean activateHandler() {
-
final OOMDumpingUncaughtExceptionHandler handler = new OOMDumpingUncaughtExceptionHandler();
return handler.activate();
}
private boolean activate() {
-
defaultHandler = Thread.getDefaultUncaughtExceptionHandler();
// replace default handler if that has not been done already
@@ -34,10 +32,8 @@ public class OOMDumpingUncaughtExceptionHandler implements UncaughtExceptionHand
}
public static boolean resetToDefault() {
-
- boolean defaultResetted = false;
-
final UncaughtExceptionHandler unspecificHandler = Thread.getDefaultUncaughtExceptionHandler();
+ boolean defaultResetted = unspecificHandler != null;
if (unspecificHandler instanceof OOMDumpingUncaughtExceptionHandler) {
final OOMDumpingUncaughtExceptionHandler handler = (OOMDumpingUncaughtExceptionHandler) unspecificHandler;
@@ -48,7 +44,6 @@ public class OOMDumpingUncaughtExceptionHandler implements UncaughtExceptionHand
}
private boolean reset() {
-
final boolean resetted = defaultReplaced;
if (defaultReplaced) {
diff --git a/main/src/cgeo/geocaching/utils/RxUtils.java b/main/src/cgeo/geocaching/utils/RxUtils.java
index 241ba78..f58348d 100644
--- a/main/src/cgeo/geocaching/utils/RxUtils.java
+++ b/main/src/cgeo/geocaching/utils/RxUtils.java
@@ -2,12 +2,21 @@ package cgeo.geocaching.utils;
import rx.Observable;
import rx.Scheduler;
+import rx.Scheduler.Worker;
+import rx.Subscription;
+import rx.android.schedulers.AndroidSchedulers;
+import rx.functions.Action0;
+import rx.functions.Action1;
import rx.observables.BlockingObservable;
+import rx.observables.ConnectableObservable;
import rx.schedulers.Schedulers;
+import rx.subscriptions.CompositeSubscription;
+import rx.subscriptions.Subscriptions;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
public class RxUtils {
@@ -25,4 +34,62 @@ public class RxUtils {
public static void waitForCompletion(final Observable<?>... observables) {
waitForCompletion(Observable.merge(observables).toBlocking());
}
+
+ /**
+ * ConnectableObservable whose subscription and unsubscription take place on a looper thread.
+ *
+ * @param <T> the type of the observable
+ */
+ public static abstract class ConnectableLooperCallbacks<T> extends ConnectableObservable<T> {
+ private static final StartableHandlerThread looperCallbacksThread =
+ new StartableHandlerThread("Looper callbacks thread", android.os.Process.THREAD_PRIORITY_BACKGROUND);
+ static {
+ looperCallbacksThread.start();
+ }
+ private static final Worker looperCallbacksWorker = AndroidSchedulers.handlerThread(looperCallbacksThread.getHandler()).createWorker();
+
+ final AtomicInteger counter = new AtomicInteger(0);
+ final long stopDelay;
+ final TimeUnit stopDelayUnit;
+
+ public ConnectableLooperCallbacks(final OnSubscribe<T> onSubscribe, final long stopDelay, final TimeUnit stopDelayUnit) {
+ super(onSubscribe);
+ this.stopDelay = stopDelay;
+ this.stopDelayUnit = stopDelayUnit;
+ }
+
+ public ConnectableLooperCallbacks(final OnSubscribe<T> onSubscribe) {
+ this(onSubscribe, 0, TimeUnit.SECONDS);
+ }
+
+ @Override
+ final public void connect(final Action1<? super Subscription> action1) {
+ final CompositeSubscription subscription = new CompositeSubscription();
+ looperCallbacksWorker.schedule(new Action0() {
+ @Override
+ public void call() {
+ if (counter.getAndIncrement() == 0) {
+ onStart();
+ }
+ subscription.add(Subscriptions.create(new Action0() {
+ @Override
+ public void call() {
+ looperCallbacksWorker.schedule(new Action0() {
+ @Override
+ public void call() {
+ if (counter.decrementAndGet() == 0) {
+ onStop();
+ }
+ }
+ }, stopDelay, stopDelayUnit);
+ }
+ }));
+ }
+ });
+ action1.call(subscription);
+ }
+
+ abstract protected void onStart();
+ abstract protected void onStop();
+ }
}
diff --git a/main/thirdparty/android/support/v4/app/FragmentListActivity.java b/main/thirdparty/android/support/v4/app/FragmentListActivity.java
index a7f8880..9641249 100644
--- a/main/thirdparty/android/support/v4/app/FragmentListActivity.java
+++ b/main/thirdparty/android/support/v4/app/FragmentListActivity.java
@@ -254,12 +254,10 @@ public class FragmentListActivity extends FragmentActivity {
/**
* Provide the cursor for the list view.
*/
- public void setListAdapter(final ListAdapter adapter) {
- synchronized (this) {
- ensureList();
- mAdapter = adapter;
- mList.setAdapter(adapter);
- }
+ public synchronized void setListAdapter(final ListAdapter adapter) {
+ ensureList();
+ mAdapter = adapter;
+ mList.setAdapter(adapter);
}
/**
diff --git a/main/thirdparty/cgeo/org/kxml2/io/KXmlSerializer.java b/main/thirdparty/cgeo/org/kxml2/io/KXmlSerializer.java
index 027ff53..01a1872 100644
--- a/main/thirdparty/cgeo/org/kxml2/io/KXmlSerializer.java
+++ b/main/thirdparty/cgeo/org/kxml2/io/KXmlSerializer.java
@@ -32,6 +32,7 @@ import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.Locale;
+@SuppressWarnings("ALL")
public class KXmlSerializer implements XmlSerializer {
// static final String UNDEFINED = ":";
diff --git a/tests/src/cgeo/geocaching/CgeoApplicationTest.java b/tests/src/cgeo/geocaching/CgeoApplicationTest.java
index ae182d7..7e7801b 100644
--- a/tests/src/cgeo/geocaching/CgeoApplicationTest.java
+++ b/tests/src/cgeo/geocaching/CgeoApplicationTest.java
@@ -165,7 +165,7 @@ public class CgeoApplicationTest extends CGeoTestCase {
deleteCacheFromDBAndLogout(cache.getGeocode());
- SearchResult search = Geocache.searchByGeocode(cache.getGeocode(), null, StoredList.TEMPORARY_LIST_ID, true, null);
+ SearchResult search = Geocache.searchByGeocode(cache.getGeocode(), null, StoredList.TEMPORARY_LIST.id, true, null);
assertThat(search).isNotNull();
assertThat(search.getGeocodes()).hasSize(1);
assertThat(search.getGeocodes().contains(cache.getGeocode())).isTrue();
@@ -180,7 +180,7 @@ public class CgeoApplicationTest extends CGeoTestCase {
deleteCacheFromDBAndLogout(cache.getGeocode());
- search = Geocache.searchByGeocode(cache.getGeocode(), null, StoredList.TEMPORARY_LIST_ID, true, null);
+ search = Geocache.searchByGeocode(cache.getGeocode(), null, StoredList.TEMPORARY_LIST.id, true, null);
assertThat(search).isNotNull();
assertThat(search.getGeocodes()).isEmpty();
}
@@ -201,7 +201,7 @@ public class CgeoApplicationTest extends CGeoTestCase {
deleteCacheFromDBAndLogout(cache.getGeocode());
- final SearchResult search = Geocache.searchByGeocode(cache.getGeocode(), null, StoredList.TEMPORARY_LIST_ID, true, null);
+ final SearchResult search = Geocache.searchByGeocode(cache.getGeocode(), null, StoredList.TEMPORARY_LIST.id, true, null);
assertThat(search).isNotNull();
assertThat(search.getGeocodes()).isEmpty();
}
diff --git a/tests/src/cgeo/geocaching/GeocacheTest.java b/tests/src/cgeo/geocaching/GeocacheTest.java
index b3ec6be..722e1cf 100644
--- a/tests/src/cgeo/geocaching/GeocacheTest.java
+++ b/tests/src/cgeo/geocaching/GeocacheTest.java
@@ -86,7 +86,7 @@ public class GeocacheTest extends CGeoTestCase {
assertThat(waypoint.getCoords()).isEqualTo(new Geopoint("N51 13.888 E007 03.444"));
// assertThat(waypoint.getNote()).isEqualTo("Test");
assertThat(waypoint.getName()).isEqualTo(CgeoApplication.getInstance().getString(R.string.cache_personal_note) + " 1");
- cache.store(StoredList.TEMPORARY_LIST_ID, null);
+ cache.store(StoredList.TEMPORARY_LIST.id, null);
}
removeCacheCompletely(geocode);
} finally {
diff --git a/tests/src/cgeo/geocaching/export/GpxSerializerTest.java b/tests/src/cgeo/geocaching/export/GpxSerializerTest.java
index 809c121..c43ad38 100644
--- a/tests/src/cgeo/geocaching/export/GpxSerializerTest.java
+++ b/tests/src/cgeo/geocaching/export/GpxSerializerTest.java
@@ -67,7 +67,7 @@ public class GpxSerializerTest extends AbstractResourceInstrumentationTestCase {
assertThat(gpxFirst.length() > 0).isTrue();
- final GPX10Parser parser = new GPX10Parser(StoredList.TEMPORARY_LIST_ID);
+ final GPX10Parser parser = new GPX10Parser(StoredList.TEMPORARY_LIST.id);
final InputStream stream = new ByteArrayInputStream(gpxFirst.getBytes(CharEncoding.UTF_8));
Collection<Geocache> caches = parser.parse(stream, null);
diff --git a/tests/src/cgeo/geocaching/files/GPXImporterTest.java b/tests/src/cgeo/geocaching/files/GPXImporterTest.java
index 02c997c..f72cf4a 100644
--- a/tests/src/cgeo/geocaching/files/GPXImporterTest.java
+++ b/tests/src/cgeo/geocaching/files/GPXImporterTest.java
@@ -266,9 +266,9 @@ public class GPXImporterTest extends AbstractResourceInstrumentationTestCase {
notifyAll();
}
- public synchronized void waitForCompletion(final long milliseconds, final int maxMessages) {
+ public synchronized void waitForCompletion(final long milliseconds) {
try {
- while (System.currentTimeMillis() - lastMessage <= milliseconds && messages.size() <= maxMessages) {
+ while (System.currentTimeMillis() - lastMessage <= milliseconds && !hasTerminatingMessage()) {
wait(milliseconds);
}
} catch (InterruptedException e) {
@@ -276,9 +276,14 @@ public class GPXImporterTest extends AbstractResourceInstrumentationTestCase {
}
}
+ private boolean hasTerminatingMessage() {
+ Message recentMessage = messages.get(messages.size() - 1);
+ return recentMessage.what == GPXImporter.IMPORT_STEP_CANCELED || recentMessage.what == GPXImporter.IMPORT_STEP_FINISHED || recentMessage.what == GPXImporter.IMPORT_STEP_FINISHED_WITH_ERROR;
+ }
+
public void waitForCompletion() {
- // Use reasonable defaults
- waitForCompletion(1000, 10);
+ // wait a maximum of 10 seconds
+ waitForCompletion(10000);
}
}
diff --git a/tests/src/cgeo/geocaching/test/AbstractResourceInstrumentationTestCase.java b/tests/src/cgeo/geocaching/test/AbstractResourceInstrumentationTestCase.java
index eaac181..2a22895 100644
--- a/tests/src/cgeo/geocaching/test/AbstractResourceInstrumentationTestCase.java
+++ b/tests/src/cgeo/geocaching/test/AbstractResourceInstrumentationTestCase.java
@@ -75,7 +75,7 @@ public abstract class AbstractResourceInstrumentationTestCase extends Instrument
protected void setUp() throws Exception {
super.setUp();
temporaryListId = DataStore.createList("Temporary unit testing");
- assertThat(temporaryListId != StoredList.TEMPORARY_LIST_ID).isTrue();
+ assertThat(temporaryListId != StoredList.TEMPORARY_LIST.id).isTrue();
assertThat(temporaryListId != StoredList.STANDARD_LIST_ID).isTrue();
}
@@ -95,7 +95,7 @@ public abstract class AbstractResourceInstrumentationTestCase extends Instrument
final protected Geocache loadCacheFromResource(int resourceId) throws IOException, ParserException {
final InputStream instream = getResourceStream(resourceId);
try {
- GPX10Parser parser = new GPX10Parser(StoredList.TEMPORARY_LIST_ID);
+ GPX10Parser parser = new GPX10Parser(StoredList.TEMPORARY_LIST.id);
Collection<Geocache> caches = parser.parse(instream, null);
assertThat(caches).isNotNull();
assertThat(caches.isEmpty()).isFalse();