diff options
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | Makefile | 30 | ||||
| -rw-r--r-- | Test.java | 6 | ||||
| -rw-r--r-- | defs.mk | 2 | ||||
| -rwxr-xr-x | get-jar-list | 30 | ||||
| -rw-r--r-- | joda-convert/Makefile | 38 | ||||
| -rw-r--r-- | joda-time/Makefile | 340 | ||||
| -rw-r--r-- | rules.mk | 20 | ||||
| -rw-r--r-- | src/org/slcl/Alert.java | 27 | ||||
| -rw-r--r-- | src/org/slcl/LoginActivity.java | 29 | ||||
| -rw-r--r-- | src/org/slcl/Main.java | 65 | ||||
| -rw-r--r-- | src/org/slcl/core/Connection.java | 56 | ||||
| -rw-r--r-- | src/org/slcl/core/Cookie.java | 39 | ||||
| -rw-r--r-- | src/org/slcl/core/Directory.java | 43 | ||||
| -rw-r--r-- | src/org/slcl/core/Login.java | 50 | ||||
| -rw-r--r-- | src/org/slcl/core/Result.java | 18 |
16 files changed, 515 insertions, 279 deletions
@@ -5,5 +5,6 @@ *.apk.idsig *.unsigned *.aligned +*.jar R.java password.secret @@ -1,16 +1,21 @@ .POSIX: .SUFFIXES: .apk .unsigned .aligned +include defs.mk + PROJECT = org.slcl -ANDROIDSDK = /usr/lib/android-sdk DX = $(ANDROIDSDK)/build-tools/debian/dx MANIFEST = AndroidManifest.xml -PLATFORM = $(ANDROIDSDK)/platforms/android-23/android.jar OBJECTS = \ + src/org/slcl/core/Connection.class \ src/org/slcl/core/Cookie.class \ + src/org/slcl/core/Directory.class \ src/org/slcl/core/Login.class \ + src/org/slcl/core/Result.class \ + src/org/slcl/Alert.class \ src/org/slcl/Directory.class \ src/org/slcl/InternalFile.class \ + src/org/slcl/LoginActivity.class \ src/org/slcl/Main.class RESOURCES = \ res/layout/activity_directory.xml \ @@ -18,6 +23,8 @@ RESOURCES = \ R = src/org/slcl/R.java PASS = password.secret DNAME = "cn=slcl, ou=slcl, o=slcl, c=ES" +JODA_TIME = joda-time/joda-time.jar +JODA_CONVERT = joda-convert/joda-convert.jar # Resources: # https://www.hanshq.net/command-line-android.html @@ -58,16 +65,29 @@ $(PROJECT).unsigned: dex/classes.dex $(MANIFEST) dex/classes.dex: .build $(MANIFEST) mkdir -p dex - $(DX) --dex --min-sdk-version=9 --output=$@ src + $(DX) --dex --min-sdk-version=9 --output=$@ src $(JODA_TIME) $(JODA_CONVERT) -.build: $(OBJECTS:.class=.java) $(R) - javac -bootclasspath $(PLATFORM) -source 1.7 -sourcepath src $(OBJECTS:.class=.java) +.build: $(OBJECTS:.class=.java) $(R) $(JODA_TIME) $(JODA_CONVERT) + javac \ + -g \ + -bootclasspath $(PLATFORM) \ + -classpath $(JODA_CONVERT):$(JODA_TIME) \ + -sourcepath src \ + $(OBJECTS:.class=.java) touch $@ +$(JODA_TIME): $(JODA_CONVERT) + +cd joda-time && $(MAKE) + +$(JODA_CONVERT): + +cd joda-convert && $(MAKE) + $(R): $(MANIFEST) $(RESOURCES) aapt package -f -m -S res -M $(MANIFEST) -I $(PLATFORM) -J src clean: + +cd joda-convert && $(MAKE) clean + +cd joda-time && $(MAKE) clean rm -f $(R) $(OBJECTS) $(PROJECT).unsigned \ $(PROJECT).aligned $(PROJECT).apk.idsig dex/classes.dex diff --git a/Test.java b/Test.java deleted file mode 100644 index 7db23ce..0000000 --- a/Test.java +++ /dev/null @@ -1,6 +0,0 @@ -public class Test { - public int a; - public void f() { - System.out.println("hi!"); - } -} @@ -0,0 +1,2 @@ +ANDROIDSDK = /usr/lib/android-sdk +PLATFORM = $(ANDROIDSDK)/platforms/android-23/android.jar diff --git a/get-jar-list b/get-jar-list new file mode 100755 index 0000000..6157fde --- /dev/null +++ b/get-jar-list @@ -0,0 +1,30 @@ +#! /bin/sh + +set -e + +usage() { + printf "%s\n" "$0 sourcepath file ..." +} + +test $# -ge 2 || (usage >&2; exit 1) +test -d "$1" || (printf "%s not a dir\n" "$1"; exit 1) + +sp="$1" + +shift 1 + +for f in $@ +do + bn=$(basename $f .class) + + while read sf + do + test -z $sf || printf -- "-C $sp %s %s " "$sf" | sed "s,$sp/,,g" + done <<-EOF + $(find $sp -iname "$bn"'$*.class') +EOF + + printf -- "-C $sp %s %s " "$f" | sed "s,$sp/,,g" +done + +printf "\n" diff --git a/joda-convert/Makefile b/joda-convert/Makefile new file mode 100644 index 0000000..d6fccad --- /dev/null +++ b/joda-convert/Makefile @@ -0,0 +1,38 @@ +SOURCEPATH = joda-convert/src/main/java +LIB = joda-convert.jar +OBJECTS = \ + $(SOURCEPATH)/org/joda/convert/FromStringConverter.class \ + $(SOURCEPATH)/org/joda/convert/Types.class \ + $(SOURCEPATH)/org/joda/convert/TypeUtils.class \ + $(SOURCEPATH)/org/joda/convert/ToString.class \ + $(SOURCEPATH)/org/joda/convert/FromStringFactory.class \ + $(SOURCEPATH)/org/joda/convert/factory/ByteObjectArrayStringConverterFactory.class \ + $(SOURCEPATH)/org/joda/convert/factory/NumericObjectArrayStringConverterFactory.class \ + $(SOURCEPATH)/org/joda/convert/factory/NumericArrayStringConverterFactory.class \ + $(SOURCEPATH)/org/joda/convert/factory/CharObjectArrayStringConverterFactory.class \ + $(SOURCEPATH)/org/joda/convert/factory/BooleanObjectArrayStringConverterFactory.class \ + $(SOURCEPATH)/org/joda/convert/factory/BooleanArrayStringConverterFactory.class \ + $(SOURCEPATH)/org/joda/convert/ToStringConverter.class \ + $(SOURCEPATH)/org/joda/convert/StringConverterFactory.class \ + $(SOURCEPATH)/org/joda/convert/FromString.class \ + $(SOURCEPATH)/org/joda/convert/TypedAdapter.class \ + $(SOURCEPATH)/org/joda/convert/TypeStringConverterFactory.class \ + $(SOURCEPATH)/org/joda/convert/TypeTokenStringConverter.class \ + $(SOURCEPATH)/org/joda/convert/OptionalDoubleStringConverter.class \ + $(SOURCEPATH)/org/joda/convert/MethodFromStringConverter.class \ + $(SOURCEPATH)/org/joda/convert/ConstructorFromStringConverter.class \ + $(SOURCEPATH)/org/joda/convert/OptionalLongStringConverter.class \ + $(SOURCEPATH)/org/joda/convert/TypeCapture.class \ + $(SOURCEPATH)/org/joda/convert/RenameHandler.class \ + $(SOURCEPATH)/org/joda/convert/TypedFromStringConverter.class \ + $(SOURCEPATH)/org/joda/convert/EnumStringConverterFactory.class \ + $(SOURCEPATH)/org/joda/convert/AnnotationStringConverterFactory.class \ + $(SOURCEPATH)/org/joda/convert/StringConverter.class \ + $(SOURCEPATH)/org/joda/convert/TypedStringConverter.class \ + $(SOURCEPATH)/org/joda/convert/JDKStringConverter.class \ + $(SOURCEPATH)/org/joda/convert/StringConvert.class \ + $(SOURCEPATH)/org/joda/convert/OptionalIntStringConverter.class \ + $(SOURCEPATH)/org/joda/convert/ReflectionStringConverter.class + +include ../defs.mk +include ../rules.mk diff --git a/joda-time/Makefile b/joda-time/Makefile index 4634e45..db171db 100644 --- a/joda-time/Makefile +++ b/joda-time/Makefile @@ -1,167 +1,173 @@ -JODA_TIME_OBJECTS = \ - joda-time/joda-time/src/main/java/org/joda/time/ReadWritableInterval.class \ - joda-time/joda-time/src/main/java/org/joda/time/DateTimeField.class \ - joda-time/joda-time/src/main/java/org/joda/time/DateTimeFieldType.class \ - joda-time/joda-time/src/main/java/org/joda/time/Weeks.class \ - joda-time/joda-time/src/main/java/org/joda/time/Hours.class \ - joda-time/joda-time/src/main/java/org/joda/time/Period.class \ - joda-time/joda-time/src/main/java/org/joda/time/format/InternalPrinter.class \ - joda-time/joda-time/src/main/java/org/joda/time/format/DateTimePrinter.class \ - joda-time/joda-time/src/main/java/org/joda/time/format/DateTimeParserInternalParser.class \ - joda-time/joda-time/src/main/java/org/joda/time/format/InternalPrinterDateTimePrinter.class \ - joda-time/joda-time/src/main/java/org/joda/time/format/DateTimeFormatterBuilder.class \ - joda-time/joda-time/src/main/java/org/joda/time/format/FormatUtils.class \ - joda-time/joda-time/src/main/java/org/joda/time/format/DateTimeFormatter.class \ - joda-time/joda-time/src/main/java/org/joda/time/format/PeriodParser.class \ - joda-time/joda-time/src/main/java/org/joda/time/format/DateTimeParser.class \ - joda-time/joda-time/src/main/java/org/joda/time/format/DateTimePrinterInternalPrinter.class \ - joda-time/joda-time/src/main/java/org/joda/time/format/PeriodPrinter.class \ - joda-time/joda-time/src/main/java/org/joda/time/format/InternalParserDateTimeParser.class \ - joda-time/joda-time/src/main/java/org/joda/time/format/InternalParser.class \ - joda-time/joda-time/src/main/java/org/joda/time/format/DateTimeFormat.class \ - joda-time/joda-time/src/main/java/org/joda/time/format/DateTimeParserBucket.class \ - joda-time/joda-time/src/main/java/org/joda/time/format/PeriodFormat.class \ - joda-time/joda-time/src/main/java/org/joda/time/format/PeriodFormatterBuilder.class \ - joda-time/joda-time/src/main/java/org/joda/time/format/ISOPeriodFormat.class \ - joda-time/joda-time/src/main/java/org/joda/time/format/PeriodFormatter.class \ - joda-time/joda-time/src/main/java/org/joda/time/format/ISODateTimeFormat.class \ - joda-time/joda-time/src/main/java/org/joda/time/ReadablePeriod.class \ - joda-time/joda-time/src/main/java/org/joda/time/PeriodType.class \ - joda-time/joda-time/src/main/java/org/joda/time/MutablePeriod.class \ - joda-time/joda-time/src/main/java/org/joda/time/Partial.class \ - joda-time/joda-time/src/main/java/org/joda/time/IllegalFieldValueException.class \ - joda-time/joda-time/src/main/java/org/joda/time/DurationField.class \ - joda-time/joda-time/src/main/java/org/joda/time/base/BaseInterval.class \ - joda-time/joda-time/src/main/java/org/joda/time/base/AbstractPeriod.class \ - joda-time/joda-time/src/main/java/org/joda/time/base/BasePartial.class \ - joda-time/joda-time/src/main/java/org/joda/time/base/AbstractDuration.class \ - joda-time/joda-time/src/main/java/org/joda/time/base/BaseDuration.class \ - joda-time/joda-time/src/main/java/org/joda/time/base/AbstractDateTime.class \ - joda-time/joda-time/src/main/java/org/joda/time/base/AbstractPartial.class \ - joda-time/joda-time/src/main/java/org/joda/time/base/AbstractInstant.class \ - joda-time/joda-time/src/main/java/org/joda/time/base/BaseSingleFieldPeriod.class \ - joda-time/joda-time/src/main/java/org/joda/time/base/BaseDateTime.class \ - joda-time/joda-time/src/main/java/org/joda/time/base/BaseLocal.class \ - joda-time/joda-time/src/main/java/org/joda/time/base/BasePeriod.class \ - joda-time/joda-time/src/main/java/org/joda/time/base/AbstractInterval.class \ - joda-time/joda-time/src/main/java/org/joda/time/Seconds.class \ - joda-time/joda-time/src/main/java/org/joda/time/UTCDateTimeZone.class \ - joda-time/joda-time/src/main/java/org/joda/time/ReadableInstant.class \ - joda-time/joda-time/src/main/java/org/joda/time/LocalTime.class \ - joda-time/joda-time/src/main/java/org/joda/time/Instant.class \ - joda-time/joda-time/src/main/java/org/joda/time/tz/DefaultNameProvider.class \ - joda-time/joda-time/src/main/java/org/joda/time/tz/UTCProvider.class \ - joda-time/joda-time/src/main/java/org/joda/time/tz/ZoneInfoCompiler.class \ - joda-time/joda-time/src/main/java/org/joda/time/tz/CachedDateTimeZone.class \ - joda-time/joda-time/src/main/java/org/joda/time/tz/ZoneInfoProvider.class \ - joda-time/joda-time/src/main/java/org/joda/time/tz/Provider.class \ - joda-time/joda-time/src/main/java/org/joda/time/tz/NameProvider.class \ - joda-time/joda-time/src/main/java/org/joda/time/tz/FixedDateTimeZone.class \ - joda-time/joda-time/src/main/java/org/joda/time/tz/DateTimeZoneBuilder.class \ - joda-time/joda-time/src/main/java/org/joda/time/tz/ZoneInfoLogger.class \ - joda-time/joda-time/src/main/java/org/joda/time/DateTimeUtils.class \ - joda-time/joda-time/src/main/java/org/joda/time/DateTime.class \ - joda-time/joda-time/src/main/java/org/joda/time/chrono/GJChronology.class \ - joda-time/joda-time/src/main/java/org/joda/time/chrono/BasicDayOfMonthDateTimeField.class \ - joda-time/joda-time/src/main/java/org/joda/time/chrono/BasicChronology.class \ - joda-time/joda-time/src/main/java/org/joda/time/chrono/CopticChronology.class \ - joda-time/joda-time/src/main/java/org/joda/time/chrono/GJDayOfWeekDateTimeField.class \ - joda-time/joda-time/src/main/java/org/joda/time/chrono/BasicGJChronology.class \ - joda-time/joda-time/src/main/java/org/joda/time/chrono/StrictChronology.class \ - joda-time/joda-time/src/main/java/org/joda/time/chrono/JulianChronology.class \ - joda-time/joda-time/src/main/java/org/joda/time/chrono/LenientChronology.class \ - joda-time/joda-time/src/main/java/org/joda/time/chrono/BasicMonthOfYearDateTimeField.class \ - joda-time/joda-time/src/main/java/org/joda/time/chrono/BasicYearDateTimeField.class \ - joda-time/joda-time/src/main/java/org/joda/time/chrono/BasicSingleEraDateTimeField.class \ - joda-time/joda-time/src/main/java/org/joda/time/chrono/ISOChronology.class \ - joda-time/joda-time/src/main/java/org/joda/time/chrono/BasicFixedMonthChronology.class \ - joda-time/joda-time/src/main/java/org/joda/time/chrono/GJYearOfEraDateTimeField.class \ - joda-time/joda-time/src/main/java/org/joda/time/chrono/IslamicChronology.class \ - joda-time/joda-time/src/main/java/org/joda/time/chrono/BasicWeekOfWeekyearDateTimeField.class \ - joda-time/joda-time/src/main/java/org/joda/time/chrono/GJLocaleSymbols.class \ - joda-time/joda-time/src/main/java/org/joda/time/chrono/ZonedChronology.class \ - joda-time/joda-time/src/main/java/org/joda/time/chrono/ISOYearOfEraDateTimeField.class \ - joda-time/joda-time/src/main/java/org/joda/time/chrono/LimitChronology.class \ - joda-time/joda-time/src/main/java/org/joda/time/chrono/BaseChronology.class \ - joda-time/joda-time/src/main/java/org/joda/time/chrono/EthiopicChronology.class \ - joda-time/joda-time/src/main/java/org/joda/time/chrono/BasicWeekyearDateTimeField.class \ - joda-time/joda-time/src/main/java/org/joda/time/chrono/GJCacheKey.class \ - joda-time/joda-time/src/main/java/org/joda/time/chrono/GregorianChronology.class \ - joda-time/joda-time/src/main/java/org/joda/time/chrono/BuddhistChronology.class \ - joda-time/joda-time/src/main/java/org/joda/time/chrono/AssembledChronology.class \ - joda-time/joda-time/src/main/java/org/joda/time/chrono/GJEraDateTimeField.class \ - joda-time/joda-time/src/main/java/org/joda/time/chrono/BasicDayOfYearDateTimeField.class \ - joda-time/joda-time/src/main/java/org/joda/time/chrono/GJMonthOfYearDateTimeField.class \ - joda-time/joda-time/src/main/java/org/joda/time/Duration.class \ - joda-time/joda-time/src/main/java/org/joda/time/field/LenientDateTimeField.class \ - joda-time/joda-time/src/main/java/org/joda/time/field/DividedDateTimeField.class \ - joda-time/joda-time/src/main/java/org/joda/time/field/DelegatedDurationField.class \ - joda-time/joda-time/src/main/java/org/joda/time/field/DecoratedDateTimeField.class \ - joda-time/joda-time/src/main/java/org/joda/time/field/DelegatedDateTimeField.class \ - joda-time/joda-time/src/main/java/org/joda/time/field/DecoratedDurationField.class \ - joda-time/joda-time/src/main/java/org/joda/time/field/PreciseDateTimeField.class \ - joda-time/joda-time/src/main/java/org/joda/time/field/ZeroIsMaxDateTimeField.class \ - joda-time/joda-time/src/main/java/org/joda/time/field/RemainderDateTimeField.class \ - joda-time/joda-time/src/main/java/org/joda/time/field/UnsupportedDateTimeField.class \ - joda-time/joda-time/src/main/java/org/joda/time/field/ScaledDurationField.class \ - joda-time/joda-time/src/main/java/org/joda/time/field/PreciseDurationDateTimeField.class \ - joda-time/joda-time/src/main/java/org/joda/time/field/SkipDateTimeField.class \ - joda-time/joda-time/src/main/java/org/joda/time/field/OffsetDateTimeField.class \ - joda-time/joda-time/src/main/java/org/joda/time/field/StrictDateTimeField.class \ - joda-time/joda-time/src/main/java/org/joda/time/field/BaseDurationField.class \ - joda-time/joda-time/src/main/java/org/joda/time/field/ImpreciseDateTimeField.class \ - joda-time/joda-time/src/main/java/org/joda/time/field/AbstractReadableInstantFieldProperty.class \ - joda-time/joda-time/src/main/java/org/joda/time/field/BaseDateTimeField.class \ - joda-time/joda-time/src/main/java/org/joda/time/field/PreciseDurationField.class \ - joda-time/joda-time/src/main/java/org/joda/time/field/SkipUndoDateTimeField.class \ - joda-time/joda-time/src/main/java/org/joda/time/field/MillisDurationField.class \ - joda-time/joda-time/src/main/java/org/joda/time/field/AbstractPartialFieldProperty.class \ - joda-time/joda-time/src/main/java/org/joda/time/field/UnsupportedDurationField.class \ - joda-time/joda-time/src/main/java/org/joda/time/field/FieldUtils.class \ - joda-time/joda-time/src/main/java/org/joda/time/ReadWritablePeriod.class \ - joda-time/joda-time/src/main/java/org/joda/time/LocalDateTime.class \ - joda-time/joda-time/src/main/java/org/joda/time/ReadableDuration.class \ - joda-time/joda-time/src/main/java/org/joda/time/Interval.class \ - joda-time/joda-time/src/main/java/org/joda/time/ReadableDateTime.class \ - joda-time/joda-time/src/main/java/org/joda/time/ReadWritableInstant.class \ - joda-time/joda-time/src/main/java/org/joda/time/YearMonth.class \ - joda-time/joda-time/src/main/java/org/joda/time/MutableDateTime.class \ - joda-time/joda-time/src/main/java/org/joda/time/DurationFieldType.class \ - joda-time/joda-time/src/main/java/org/joda/time/Days.class \ - joda-time/joda-time/src/main/java/org/joda/time/ReadWritableDateTime.class \ - joda-time/joda-time/src/main/java/org/joda/time/Minutes.class \ - joda-time/joda-time/src/main/java/org/joda/time/DateTimeConstants.class \ - joda-time/joda-time/src/main/java/org/joda/time/DateTimeZone.class \ - joda-time/joda-time/src/main/java/org/joda/time/DateMidnight.class \ - joda-time/joda-time/src/main/java/org/joda/time/LocalDate.class \ - joda-time/joda-time/src/main/java/org/joda/time/DateTimeComparator.class \ - joda-time/joda-time/src/main/java/org/joda/time/MonthDay.class \ - joda-time/joda-time/src/main/java/org/joda/time/Years.class \ - joda-time/joda-time/src/main/java/org/joda/time/convert/DurationConverter.class \ - joda-time/joda-time/src/main/java/org/joda/time/convert/InstantConverter.class \ - joda-time/joda-time/src/main/java/org/joda/time/convert/PartialConverter.class \ - joda-time/joda-time/src/main/java/org/joda/time/convert/DateConverter.class \ - joda-time/joda-time/src/main/java/org/joda/time/convert/IntervalConverter.class \ - joda-time/joda-time/src/main/java/org/joda/time/convert/CalendarConverter.class \ - joda-time/joda-time/src/main/java/org/joda/time/convert/PeriodConverter.class \ - joda-time/joda-time/src/main/java/org/joda/time/convert/ConverterManager.class \ - joda-time/joda-time/src/main/java/org/joda/time/convert/ReadableInstantConverter.class \ - joda-time/joda-time/src/main/java/org/joda/time/convert/ReadablePeriodConverter.class \ - joda-time/joda-time/src/main/java/org/joda/time/convert/NullConverter.class \ - joda-time/joda-time/src/main/java/org/joda/time/convert/ReadablePartialConverter.class \ - joda-time/joda-time/src/main/java/org/joda/time/convert/StringConverter.class \ - joda-time/joda-time/src/main/java/org/joda/time/convert/AbstractConverter.class \ - joda-time/joda-time/src/main/java/org/joda/time/convert/LongConverter.class \ - joda-time/joda-time/src/main/java/org/joda/time/convert/Converter.class \ - joda-time/joda-time/src/main/java/org/joda/time/convert/ReadableDurationConverter.class \ - joda-time/joda-time/src/main/java/org/joda/time/convert/ReadableIntervalConverter.class \ - joda-time/joda-time/src/main/java/org/joda/time/convert/ConverterSet.class \ - joda-time/joda-time/src/main/java/org/joda/time/MutableInterval.class \ - joda-time/joda-time/src/main/java/org/joda/time/YearMonthDay.class \ - joda-time/joda-time/src/main/java/org/joda/time/TimeOfDay.class \ - joda-time/joda-time/src/main/java/org/joda/time/ReadablePartial.class \ - joda-time/joda-time/src/main/java/org/joda/time/JodaTimePermission.class \ - joda-time/joda-time/src/main/java/org/joda/time/IllegalInstantException.class \ - joda-time/joda-time/src/main/java/org/joda/time/ReadableInterval.class \ - joda-time/joda-time/src/main/java/org/joda/time/Months.class \ - joda-time/joda-time/src/main/java/org/joda/time/Chronology.class +DEPS = ../joda-convert/joda-convert.jar +LIB = joda-time.jar +SOURCEPATH = joda-time/src/main/java +OBJECTS = \ + $(SOURCEPATH)/org/joda/time/ReadWritableInterval.class \ + $(SOURCEPATH)/org/joda/time/DateTimeField.class \ + $(SOURCEPATH)/org/joda/time/DateTimeFieldType.class \ + $(SOURCEPATH)/org/joda/time/Weeks.class \ + $(SOURCEPATH)/org/joda/time/Hours.class \ + $(SOURCEPATH)/org/joda/time/Period.class \ + $(SOURCEPATH)/org/joda/time/format/InternalPrinter.class \ + $(SOURCEPATH)/org/joda/time/format/DateTimePrinter.class \ + $(SOURCEPATH)/org/joda/time/format/DateTimeParserInternalParser.class \ + $(SOURCEPATH)/org/joda/time/format/InternalPrinterDateTimePrinter.class \ + $(SOURCEPATH)/org/joda/time/format/DateTimeFormatterBuilder.class \ + $(SOURCEPATH)/org/joda/time/format/FormatUtils.class \ + $(SOURCEPATH)/org/joda/time/format/DateTimeFormatter.class \ + $(SOURCEPATH)/org/joda/time/format/PeriodParser.class \ + $(SOURCEPATH)/org/joda/time/format/DateTimeParser.class \ + $(SOURCEPATH)/org/joda/time/format/DateTimePrinterInternalPrinter.class \ + $(SOURCEPATH)/org/joda/time/format/PeriodPrinter.class \ + $(SOURCEPATH)/org/joda/time/format/InternalParserDateTimeParser.class \ + $(SOURCEPATH)/org/joda/time/format/InternalParser.class \ + $(SOURCEPATH)/org/joda/time/format/DateTimeFormat.class \ + $(SOURCEPATH)/org/joda/time/format/DateTimeParserBucket.class \ + $(SOURCEPATH)/org/joda/time/format/PeriodFormat.class \ + $(SOURCEPATH)/org/joda/time/format/PeriodFormatterBuilder.class \ + $(SOURCEPATH)/org/joda/time/format/ISOPeriodFormat.class \ + $(SOURCEPATH)/org/joda/time/format/PeriodFormatter.class \ + $(SOURCEPATH)/org/joda/time/format/ISODateTimeFormat.class \ + $(SOURCEPATH)/org/joda/time/ReadablePeriod.class \ + $(SOURCEPATH)/org/joda/time/PeriodType.class \ + $(SOURCEPATH)/org/joda/time/MutablePeriod.class \ + $(SOURCEPATH)/org/joda/time/Partial.class \ + $(SOURCEPATH)/org/joda/time/IllegalFieldValueException.class \ + $(SOURCEPATH)/org/joda/time/DurationField.class \ + $(SOURCEPATH)/org/joda/time/base/BaseInterval.class \ + $(SOURCEPATH)/org/joda/time/base/AbstractPeriod.class \ + $(SOURCEPATH)/org/joda/time/base/BasePartial.class \ + $(SOURCEPATH)/org/joda/time/base/AbstractDuration.class \ + $(SOURCEPATH)/org/joda/time/base/BaseDuration.class \ + $(SOURCEPATH)/org/joda/time/base/AbstractDateTime.class \ + $(SOURCEPATH)/org/joda/time/base/AbstractPartial.class \ + $(SOURCEPATH)/org/joda/time/base/AbstractInstant.class \ + $(SOURCEPATH)/org/joda/time/base/BaseSingleFieldPeriod.class \ + $(SOURCEPATH)/org/joda/time/base/BaseDateTime.class \ + $(SOURCEPATH)/org/joda/time/base/BaseLocal.class \ + $(SOURCEPATH)/org/joda/time/base/BasePeriod.class \ + $(SOURCEPATH)/org/joda/time/base/AbstractInterval.class \ + $(SOURCEPATH)/org/joda/time/Seconds.class \ + $(SOURCEPATH)/org/joda/time/UTCDateTimeZone.class \ + $(SOURCEPATH)/org/joda/time/ReadableInstant.class \ + $(SOURCEPATH)/org/joda/time/LocalTime.class \ + $(SOURCEPATH)/org/joda/time/Instant.class \ + $(SOURCEPATH)/org/joda/time/tz/DefaultNameProvider.class \ + $(SOURCEPATH)/org/joda/time/tz/UTCProvider.class \ + $(SOURCEPATH)/org/joda/time/tz/ZoneInfoCompiler.class \ + $(SOURCEPATH)/org/joda/time/tz/CachedDateTimeZone.class \ + $(SOURCEPATH)/org/joda/time/tz/ZoneInfoProvider.class \ + $(SOURCEPATH)/org/joda/time/tz/Provider.class \ + $(SOURCEPATH)/org/joda/time/tz/NameProvider.class \ + $(SOURCEPATH)/org/joda/time/tz/FixedDateTimeZone.class \ + $(SOURCEPATH)/org/joda/time/tz/DateTimeZoneBuilder.class \ + $(SOURCEPATH)/org/joda/time/tz/ZoneInfoLogger.class \ + $(SOURCEPATH)/org/joda/time/DateTimeUtils.class \ + $(SOURCEPATH)/org/joda/time/DateTime.class \ + $(SOURCEPATH)/org/joda/time/chrono/GJChronology.class \ + $(SOURCEPATH)/org/joda/time/chrono/BasicDayOfMonthDateTimeField.class \ + $(SOURCEPATH)/org/joda/time/chrono/BasicChronology.class \ + $(SOURCEPATH)/org/joda/time/chrono/CopticChronology.class \ + $(SOURCEPATH)/org/joda/time/chrono/GJDayOfWeekDateTimeField.class \ + $(SOURCEPATH)/org/joda/time/chrono/BasicGJChronology.class \ + $(SOURCEPATH)/org/joda/time/chrono/StrictChronology.class \ + $(SOURCEPATH)/org/joda/time/chrono/JulianChronology.class \ + $(SOURCEPATH)/org/joda/time/chrono/LenientChronology.class \ + $(SOURCEPATH)/org/joda/time/chrono/BasicMonthOfYearDateTimeField.class \ + $(SOURCEPATH)/org/joda/time/chrono/BasicYearDateTimeField.class \ + $(SOURCEPATH)/org/joda/time/chrono/BasicSingleEraDateTimeField.class \ + $(SOURCEPATH)/org/joda/time/chrono/ISOChronology.class \ + $(SOURCEPATH)/org/joda/time/chrono/BasicFixedMonthChronology.class \ + $(SOURCEPATH)/org/joda/time/chrono/GJYearOfEraDateTimeField.class \ + $(SOURCEPATH)/org/joda/time/chrono/IslamicChronology.class \ + $(SOURCEPATH)/org/joda/time/chrono/BasicWeekOfWeekyearDateTimeField.class \ + $(SOURCEPATH)/org/joda/time/chrono/GJLocaleSymbols.class \ + $(SOURCEPATH)/org/joda/time/chrono/ZonedChronology.class \ + $(SOURCEPATH)/org/joda/time/chrono/ISOYearOfEraDateTimeField.class \ + $(SOURCEPATH)/org/joda/time/chrono/LimitChronology.class \ + $(SOURCEPATH)/org/joda/time/chrono/BaseChronology.class \ + $(SOURCEPATH)/org/joda/time/chrono/EthiopicChronology.class \ + $(SOURCEPATH)/org/joda/time/chrono/BasicWeekyearDateTimeField.class \ + $(SOURCEPATH)/org/joda/time/chrono/GJCacheKey.class \ + $(SOURCEPATH)/org/joda/time/chrono/GregorianChronology.class \ + $(SOURCEPATH)/org/joda/time/chrono/BuddhistChronology.class \ + $(SOURCEPATH)/org/joda/time/chrono/AssembledChronology.class \ + $(SOURCEPATH)/org/joda/time/chrono/GJEraDateTimeField.class \ + $(SOURCEPATH)/org/joda/time/chrono/BasicDayOfYearDateTimeField.class \ + $(SOURCEPATH)/org/joda/time/chrono/GJMonthOfYearDateTimeField.class \ + $(SOURCEPATH)/org/joda/time/Duration.class \ + $(SOURCEPATH)/org/joda/time/field/LenientDateTimeField.class \ + $(SOURCEPATH)/org/joda/time/field/DividedDateTimeField.class \ + $(SOURCEPATH)/org/joda/time/field/DelegatedDurationField.class \ + $(SOURCEPATH)/org/joda/time/field/DecoratedDateTimeField.class \ + $(SOURCEPATH)/org/joda/time/field/DelegatedDateTimeField.class \ + $(SOURCEPATH)/org/joda/time/field/DecoratedDurationField.class \ + $(SOURCEPATH)/org/joda/time/field/PreciseDateTimeField.class \ + $(SOURCEPATH)/org/joda/time/field/ZeroIsMaxDateTimeField.class \ + $(SOURCEPATH)/org/joda/time/field/RemainderDateTimeField.class \ + $(SOURCEPATH)/org/joda/time/field/UnsupportedDateTimeField.class \ + $(SOURCEPATH)/org/joda/time/field/ScaledDurationField.class \ + $(SOURCEPATH)/org/joda/time/field/PreciseDurationDateTimeField.class \ + $(SOURCEPATH)/org/joda/time/field/SkipDateTimeField.class \ + $(SOURCEPATH)/org/joda/time/field/OffsetDateTimeField.class \ + $(SOURCEPATH)/org/joda/time/field/StrictDateTimeField.class \ + $(SOURCEPATH)/org/joda/time/field/BaseDurationField.class \ + $(SOURCEPATH)/org/joda/time/field/ImpreciseDateTimeField.class \ + $(SOURCEPATH)/org/joda/time/field/AbstractReadableInstantFieldProperty.class \ + $(SOURCEPATH)/org/joda/time/field/BaseDateTimeField.class \ + $(SOURCEPATH)/org/joda/time/field/PreciseDurationField.class \ + $(SOURCEPATH)/org/joda/time/field/SkipUndoDateTimeField.class \ + $(SOURCEPATH)/org/joda/time/field/MillisDurationField.class \ + $(SOURCEPATH)/org/joda/time/field/AbstractPartialFieldProperty.class \ + $(SOURCEPATH)/org/joda/time/field/UnsupportedDurationField.class \ + $(SOURCEPATH)/org/joda/time/field/FieldUtils.class \ + $(SOURCEPATH)/org/joda/time/ReadWritablePeriod.class \ + $(SOURCEPATH)/org/joda/time/LocalDateTime.class \ + $(SOURCEPATH)/org/joda/time/ReadableDuration.class \ + $(SOURCEPATH)/org/joda/time/Interval.class \ + $(SOURCEPATH)/org/joda/time/ReadableDateTime.class \ + $(SOURCEPATH)/org/joda/time/ReadWritableInstant.class \ + $(SOURCEPATH)/org/joda/time/YearMonth.class \ + $(SOURCEPATH)/org/joda/time/MutableDateTime.class \ + $(SOURCEPATH)/org/joda/time/DurationFieldType.class \ + $(SOURCEPATH)/org/joda/time/Days.class \ + $(SOURCEPATH)/org/joda/time/ReadWritableDateTime.class \ + $(SOURCEPATH)/org/joda/time/Minutes.class \ + $(SOURCEPATH)/org/joda/time/DateTimeConstants.class \ + $(SOURCEPATH)/org/joda/time/DateTimeZone.class \ + $(SOURCEPATH)/org/joda/time/DateMidnight.class \ + $(SOURCEPATH)/org/joda/time/LocalDate.class \ + $(SOURCEPATH)/org/joda/time/DateTimeComparator.class \ + $(SOURCEPATH)/org/joda/time/MonthDay.class \ + $(SOURCEPATH)/org/joda/time/Years.class \ + $(SOURCEPATH)/org/joda/time/convert/DurationConverter.class \ + $(SOURCEPATH)/org/joda/time/convert/InstantConverter.class \ + $(SOURCEPATH)/org/joda/time/convert/PartialConverter.class \ + $(SOURCEPATH)/org/joda/time/convert/DateConverter.class \ + $(SOURCEPATH)/org/joda/time/convert/IntervalConverter.class \ + $(SOURCEPATH)/org/joda/time/convert/CalendarConverter.class \ + $(SOURCEPATH)/org/joda/time/convert/PeriodConverter.class \ + $(SOURCEPATH)/org/joda/time/convert/ConverterManager.class \ + $(SOURCEPATH)/org/joda/time/convert/ReadableInstantConverter.class \ + $(SOURCEPATH)/org/joda/time/convert/ReadablePeriodConverter.class \ + $(SOURCEPATH)/org/joda/time/convert/NullConverter.class \ + $(SOURCEPATH)/org/joda/time/convert/ReadablePartialConverter.class \ + $(SOURCEPATH)/org/joda/time/convert/StringConverter.class \ + $(SOURCEPATH)/org/joda/time/convert/AbstractConverter.class \ + $(SOURCEPATH)/org/joda/time/convert/LongConverter.class \ + $(SOURCEPATH)/org/joda/time/convert/Converter.class \ + $(SOURCEPATH)/org/joda/time/convert/ReadableDurationConverter.class \ + $(SOURCEPATH)/org/joda/time/convert/ReadableIntervalConverter.class \ + $(SOURCEPATH)/org/joda/time/convert/ConverterSet.class \ + $(SOURCEPATH)/org/joda/time/MutableInterval.class \ + $(SOURCEPATH)/org/joda/time/YearMonthDay.class \ + $(SOURCEPATH)/org/joda/time/TimeOfDay.class \ + $(SOURCEPATH)/org/joda/time/ReadablePartial.class \ + $(SOURCEPATH)/org/joda/time/JodaTimePermission.class \ + $(SOURCEPATH)/org/joda/time/IllegalInstantException.class \ + $(SOURCEPATH)/org/joda/time/ReadableInterval.class \ + $(SOURCEPATH)/org/joda/time/Months.class \ + $(SOURCEPATH)/org/joda/time/Chronology.class + +include ../defs.mk +include ../rules.mk diff --git a/rules.mk b/rules.mk new file mode 100644 index 0000000..12d9dc9 --- /dev/null +++ b/rules.mk @@ -0,0 +1,20 @@ +.POSIX: +.SUFFIXES: + +all: $(LIB) + +$(LIB): $(OBJECTS:.class=.java) + DEPS=$(DEPS) && \ + javac \ + -g \ + -bootclasspath $(PLATFORM) \ + $${DEPS:+-classpath $$DEPS} \ + -sourcepath $(SOURCEPATH) \ + $(OBJECTS:.class=.java) + TMP=$$(mktemp) && \ + trap "rm $$TMP" EXIT && \ + ../get-jar-list $(SOURCEPATH) $(OBJECTS) > $$TMP && \ + jar cf $@ @$$TMP + +clean: + rm -f $(OBJECTS) $(LIB) diff --git a/src/org/slcl/Alert.java b/src/org/slcl/Alert.java new file mode 100644 index 0000000..1b93550 --- /dev/null +++ b/src/org/slcl/Alert.java @@ -0,0 +1,27 @@ +package org.slcl; + +import android.app.AlertDialog; +import android.app.AlertDialog.Builder; +import android.content.Context; +import android.content.DialogInterface; + +public final class Alert { + public Alert(final Context c, final String message) + { + final AlertDialog.Builder b = new AlertDialog.Builder(c); + + b.setMessage(message); + b.setPositiveButton("Close", + new DialogInterface.OnClickListener() { + public void onClick(final DialogInterface dialog, + final int id) { + dialog.cancel(); + } + } + ); + + final AlertDialog d = b.create(); + + d.show(); + } +} diff --git a/src/org/slcl/LoginActivity.java b/src/org/slcl/LoginActivity.java index 79e2ed4..dd58b9b 100644 --- a/src/org/slcl/LoginActivity.java +++ b/src/org/slcl/LoginActivity.java @@ -20,6 +20,7 @@ package org.slcl; import org.slcl.core.Cookie; import org.slcl.core.Login; +import org.slcl.core.Result; import org.slcl.Directory; import org.slcl.InternalFile; import java.net.URLEncoder; @@ -88,15 +89,14 @@ public final class LoginActivity extends Activity { t.execute(p); } catch (final IOException e) { - //error.setText("Exception: " + e.getMessage()); + new Alert(LoginActivity.this, e.getMessage()); } } }); } - // https://stackoverflow.com/questions/6053602/what-arguments-are-passed-into-asynctaskarg1-arg2-arg3 private final class LoginTask - extends AsyncTask<LoginParams, String, String> + extends AsyncTask<LoginParams, Void, Result<String>> { ProgressDialog dialog; @@ -108,7 +108,7 @@ public final class LoginActivity extends Activity { } @Override - protected String doInBackground(final LoginParams... params) + protected Result<String> doInBackground(final LoginParams... params) { try { final LoginParams p = params[0]; @@ -120,27 +120,28 @@ public final class LoginActivity extends Activity { final Cookie c = new Cookie(p.username, cookie); c.store(f.getFile()); - return ""; + return new Result<String>(); } catch (final IOException e) { - System.out.println(e.getMessage()); - return e.getMessage(); + return new Result<String>("Could not connect: " + + e.getMessage()); } } @Override - protected void onProgressUpdate(final String... text) + protected void onProgressUpdate(final Void... text) { } @Override - protected void onPostExecute(final String result) + protected void onPostExecute(final Result<String> result) { - Intent intent = new Intent(LoginActivity.this, Directory.class); - dialog.dismiss(); - startActivity(intent); - // TODO: review errors. - //error.setText("Exception: " + e.getMessage()); + + if (result.success) { + startActivity(new Intent(LoginActivity.this, Directory.class)); + } else { + new Alert(LoginActivity.this, result.error); + } } } } diff --git a/src/org/slcl/Main.java b/src/org/slcl/Main.java index 8ac8c55..34a3b92 100644 --- a/src/org/slcl/Main.java +++ b/src/org/slcl/Main.java @@ -35,59 +35,34 @@ public final class Main extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { - final LoadTask t = new LoadTask(); - super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); - t.execute(); - } - - private final class LoadTask extends AsyncTask<String, String, Cookie> - { - ProgressDialog dialog; - - @Override - protected void onPreExecute() - { - dialog = dialog.show(Main.this, "ProgressDialog", - "Retrieving credentials"); - } - - @Override - protected Cookie doInBackground(final String... args) - { - try { - final InternalFile f = new InternalFile( - getApplicationContext(), "login"); - final Cookie c = new Cookie(f.getFile()); - return c; - } catch (final IOException e) { - System.out.println(e.getMessage()); - return null; - } - } + final Cookie c = getLogin(); + final Intent intent; - @Override - protected void onProgressUpdate(final String... params) - { + if (c == null) { + intent = new Intent(Main.this, LoginActivity.class); + } else { + intent = new Intent(Main.this, Directory.class); + // TODO: split cookie with ';' (expiration date, etc.). + intent.putExtra(Directory.EXTRA_ID, c.getCookie()); } - @Override - protected void onPostExecute(final Cookie cookie) - { - final Intent intent; + startActivity(intent); + } - if (cookie == null) { - intent = new Intent(Main.this, LoginActivity.class); - } else { - intent = new Intent(Main.this, Directory.class); - // TODO: split cookie with ';' (expiration date, etc.). - intent.putExtra(Directory.EXTRA_ID, cookie.getCookie()); - } + private Cookie getLogin() + { + try { + final Context context = getApplicationContext(); + final InternalFile f = new InternalFile(context, "login"); + final Cookie cookie = new Cookie(f.getFile()); - dialog.dismiss(); - startActivity(intent); + return cookie; + } catch (final IOException e) { + System.out.println(e.getMessage()); + return null; } } } diff --git a/src/org/slcl/core/Connection.java b/src/org/slcl/core/Connection.java new file mode 100644 index 0000000..9c6cad5 --- /dev/null +++ b/src/org/slcl/core/Connection.java @@ -0,0 +1,56 @@ +/* + * slcl-android, an Android frontend for slcl + * Copyright (C) 2023-2024 Xavier Del Campo Romero + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +package org.slcl.core; + +import java.io.IOException; +import java.net.URL; +import java.net.HttpURLConnection; +import javax.net.ssl.HttpsURLConnection; + +public final class Connection +{ + final HttpURLConnection c; + + public Connection(final boolean https, final String orig_url) + throws IOException + { + String url = orig_url; + + if (!url.startsWith("https://") && https) { + url = "https://" + url; + } + else if (!url.startsWith("http://")) { + url = "http://" + url; + } + + URL u = new URL(url); + + if (https) { + c = (HttpsURLConnection)u.openConnection(); + } + else { + c = (HttpURLConnection)u.openConnection(); + } + } + + public HttpURLConnection getConnection() + { + return c; + } +} diff --git a/src/org/slcl/core/Cookie.java b/src/org/slcl/core/Cookie.java index 86f64b5..3bdd320 100644 --- a/src/org/slcl/core/Cookie.java +++ b/src/org/slcl/core/Cookie.java @@ -24,8 +24,9 @@ import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStreamReader; import java.io.IOException; -import java.text.ParsePosition; -import java.text.SimpleDateFormat; +import org.joda.time.DateTime; +import org.joda.time.format.DateTimeFormat; +import org.joda.time.format.DateTimeFormatter; import java.util.Date; import java.util.List; @@ -50,7 +51,14 @@ public final class Cookie { final FileInputStream fis = new FileInputStream(f); final InputStreamReader ir = new InputStreamReader(fis); final BufferedReader r = new BufferedReader(ir); - final Results res = from_data(null, r.readLine()); + final String data = r.readLine(); + + if (data == null) { + fis.close(); + throw new IOException("empty file"); + } + + final Results res = from_data(null, data); username = res.username; cookie = res.cookie; @@ -59,8 +67,8 @@ public final class Cookie { } private final class CookieDate { - final private String FMT = "EEE, dd MMM yyyy hh:mm:ss z"; - Date date; + final private String FMT = "EEE, dd MMM yyyy HH:mm:ss z"; + final DateTime date; public CookieDate(final String[] tokens) throws IOException { @@ -77,14 +85,17 @@ public final class Cookie { continue; } - ParsePosition pos = new ParsePosition(0); - final SimpleDateFormat fmt = new SimpleDateFormat(FMT); - final Date d = fmt.parse(date_tokens[1], pos); + final DateTimeFormatter fmt = DateTimeFormat.forPattern(FMT); - if (d != null) { - // TODO: check pos. - date = d; + try { + final DateTime dt = fmt.parseDateTime(date_tokens[1]); + + date = dt; return; + } catch (final IllegalArgumentException e) { + throw new IOException(e.getMessage()); + } catch (final UnsupportedOperationException e) { + throw new IOException(e.getMessage()); } } @@ -93,12 +104,10 @@ public final class Cookie { public String toString() { - final SimpleDateFormat fmt = new SimpleDateFormat(FMT); - - return fmt.format(date, null, null).toString(); + return date.toString(FMT); } - public Date getDate() { + public DateTime getDate() { return date; } } diff --git a/src/org/slcl/core/Directory.java b/src/org/slcl/core/Directory.java new file mode 100644 index 0000000..1ac91e4 --- /dev/null +++ b/src/org/slcl/core/Directory.java @@ -0,0 +1,43 @@ +/* + * slcl-android, an Android frontend for slcl + * Copyright (C) 2023-2024 Xavier Del Campo Romero + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +package org.slcl.core; + +import org.slcl.core.Connection; +import org.slcl.core.Cookie; +import java.io.IOException; +import java.io.OutputStream; +import java.net.HttpURLConnection; + +public final class Directory +{ + String[] files, dirs; + + public Directory(final Cookie cookie, final boolean https, + final String url, final String path) throws IOException + { + final Connection conn = new Connection(https, url + "/user" + path); + final HttpURLConnection c = conn.getConnection(); + + c.setRequestMethod("GET"); + c.setInstanceFollowRedirects(false); + c.setReadTimeout(5000); + + OutputStream os = c.getOutputStream(); + } +} diff --git a/src/org/slcl/core/Login.java b/src/org/slcl/core/Login.java index d5b9267..e52a01a 100644 --- a/src/org/slcl/core/Login.java +++ b/src/org/slcl/core/Login.java @@ -18,45 +18,26 @@ package org.slcl.core; +import org.slcl.core.Connection; import java.io.OutputStream; import java.io.IOException; -import java.net.URL; -import java.net.URLConnection; import java.net.HttpURLConnection; import java.util.List; import java.util.Map; -import javax.net.ssl.HttpsURLConnection; public final class Login { - public String login(final boolean https, String url, final String username, - final String password) throws IOException { - - if (!url.startsWith("https://") && https) { - url = "https://" + url; - } - else if (!url.startsWith("http://")) { - url = "http://" + url; - } - - url += "/login"; - - final String data = "username=" + username + "&password=" + password; - - URL u = new URL(url); - HttpURLConnection c; - - if (https) { - c = (HttpsURLConnection)u.openConnection(); - } - else { - c = (HttpURLConnection)u.openConnection(); - } + public String login(final boolean https, final String url, + final String username, final String password) throws IOException + { + final Connection conn = new Connection(https, url + "/login"); + final HttpURLConnection c = conn.getConnection(); c.setRequestMethod("POST"); c.setInstanceFollowRedirects(false); c.setReadTimeout(5000); - OutputStream os = c.getOutputStream(); + final OutputStream os = c.getOutputStream(); + final String data = "username=" + username + "&password=" + password; os.write(data.getBytes()); @@ -74,6 +55,21 @@ public final class Login { { final Map<String,List<String>> headers = c.getHeaderFields(); final List<String> cookies = headers.get("Set-Cookie"); + final List<String> locations = headers.get("Location"); + + if (locations == null) { + throw new IOException("Expected Location header"); + } else if (locations.size() != 1) { + throw new IOException("Expected only 1 Location header"); + } + + final String location = locations.toArray(new String[0])[0], + exp_location = "/user/"; + + if (!location.equals(exp_location)) { + throw new IOException("Expected redirection to " + + exp_location + ", got \"" + location + "\""); + } if (cookies != null) { if (cookies.size() != 1) { diff --git a/src/org/slcl/core/Result.java b/src/org/slcl/core/Result.java new file mode 100644 index 0000000..2bffdb4 --- /dev/null +++ b/src/org/slcl/core/Result.java @@ -0,0 +1,18 @@ +package org.slcl.core; + +public final class Result<T> { + public final boolean success; + public final T error; + + public Result() + { + success = true; + error = null; + } + + public Result(final T error) + { + success = false; + this.error = error; + } +} |
