├── .gitignore
└── ex
├── BarrierTaskGang
├── .classpath
├── .gitignore
├── .project
└── src
│ ├── BarrierTaskGangTest.java
│ ├── CyclicSearchWithCyclicBarrier.java
│ ├── CyclicSearchWithPhaser.java
│ ├── OneShotSearchWithCountDownLatch.java
│ ├── SearchResults.java
│ ├── SearchTaskGangCommon.java
│ ├── SearchTaskGangCommonCyclic.java
│ └── TaskGang.java
├── BuggyQueue
├── .classpath
├── .project
└── src
│ ├── BuggyQueueTest.java
│ └── SimpleQueue.java
├── DeadlockQueue
├── .classpath
├── .project
└── src
│ ├── DeadlockTest.java
│ └── SimpleQueue.java
├── DownloadApplication
├── .classpath
├── .project
├── AndroidManifest.xml
├── gen
│ └── edu
│ │ └── vuum
│ │ └── mocca
│ │ ├── BuildConfig.java
│ │ └── R.java
├── project.properties
├── res
│ ├── drawable-hdpi
│ │ ├── default_image.png
│ │ ├── ic_action_search.png
│ │ └── ic_launcher.png
│ ├── drawable-ldpi
│ │ ├── ic_icon.png
│ │ └── ic_launcher.png
│ ├── drawable-mdpi
│ │ ├── default_image.png
│ │ ├── ic_action_search.png
│ │ └── ic_launcher.png
│ ├── drawable-xhdpi
│ │ ├── default_image.png
│ │ ├── ic_action_search.png
│ │ └── ic_launcher.png
│ ├── layout
│ │ ├── main.xml
│ │ └── main.xml.~1~
│ ├── menu
│ │ └── options.xml
│ ├── values-v11
│ │ └── styles.xml
│ ├── values-v14
│ │ └── styles.xml
│ └── values
│ │ ├── strings.xml
│ │ └── styles.xml
└── src
│ └── edu
│ └── vuum
│ └── mocca
│ ├── DownloadActivity.java
│ └── DownloadService.java
├── ImageStream
├── .classpath
├── .project
├── DownloadImages
│ ├── GrayScaleFilter
│ │ ├── douglass.jpg
│ │ ├── ironbound.jpg
│ │ ├── ka.png
│ │ ├── lil-doug.jpg
│ │ ├── uci.png
│ │ └── wm.jpg
│ └── NullFilter
│ │ ├── douglass.jpg
│ │ ├── ironbound.jpg
│ │ ├── ka.png
│ │ ├── lil-doug.jpg
│ │ ├── uci.png
│ │ └── wm.jpg
└── src
│ └── example
│ └── imagestream
│ ├── BufferedImage.java
│ ├── Filter.java
│ ├── FilterDecorator.java
│ ├── GrayScaleFilter.java
│ ├── Image.java
│ ├── ImageEntity.java
│ ├── ImageStream.java
│ ├── ImageStreamCompletableFuture.java
│ ├── ImageStreamParallel.java
│ ├── ImageStreamSequential.java
│ ├── MainConsole.java
│ ├── NullFilter.java
│ ├── Options.java
│ ├── OutputFilterDecorator.java
│ ├── PlatformStrategy.java
│ ├── PlatformStrategyConsole.java
│ ├── PlatformStrategyFactory.java
│ └── StreamGang.java
├── ImageStreamWeb
├── .classpath
├── .project
├── WebContent
│ ├── META-INF
│ │ └── MANIFEST.MF
│ └── WEB-INF
│ │ ├── lib
│ │ └── gson-2.3.1.jar
│ │ └── web.xml
└── src
│ ├── example
│ ├── BufferedImage.java
│ ├── Image.java
│ ├── ImageEntity.java
│ ├── ImageStream.java
│ ├── ImageStreamCompletableFuture.java
│ ├── ImageStreamParallel.java
│ ├── ImageStreamSequential.java
│ ├── ImageStreamServlet.java
│ ├── MainConsole.java
│ ├── Options.java
│ ├── PlatformStrategy.java
│ ├── PlatformStrategyConsole.java
│ ├── PlatformStrategyFactory.java
│ ├── PlatformStrategyProxy.java
│ └── StreamGang.java
│ └── filters
│ ├── Filter.java
│ ├── FilterDecorator.java
│ ├── GrayScaleFilter.java
│ ├── NullFilter.java
│ └── OutputFilterDecorator.java
├── ImageTaskGang
├── .classpath
├── .project
├── AndroidManifest.xml
├── libs
│ ├── META-INF
│ │ ├── MANIFEST.MF
│ │ └── maven
│ │ │ └── com.squareup.retrofit
│ │ │ └── retrofit
│ │ │ ├── pom.properties
│ │ │ └── pom.xml
│ ├── android-support-v4.jar
│ ├── gson-2.3.1.jar
│ └── retrofit-1.9.0.jar
├── proguard-project.txt
├── project.properties
├── res
│ ├── drawable-hdpi
│ │ └── ic_launcher.png
│ ├── drawable-mdpi
│ │ └── ic_launcher.png
│ ├── drawable-xhdpi
│ │ └── ic_launcher.png
│ ├── layout
│ │ ├── activity_main.xml
│ │ ├── activity_result.xml
│ │ ├── list_item.xml
│ │ ├── result_button.xml
│ │ └── suggestion_item.xml
│ ├── values-v11
│ │ └── styles.xml
│ ├── values-v14
│ │ └── styles.xml
│ └── values
│ │ ├── strings.xml
│ │ └── styles.xml
└── src
│ └── example
│ └── imagetaskgang
│ ├── BitmapImage.java
│ ├── BufferedImage.java
│ ├── Image.java
│ ├── ImageEntity.java
│ ├── ImageTaskGang.java
│ ├── MainActivity.java
│ ├── MainConsole.java
│ ├── Options.java
│ ├── PlatformStrategy.java
│ ├── PlatformStrategyAndroid.java
│ ├── PlatformStrategyConsole.java
│ ├── PlatformStrategyFactory.java
│ ├── ResultsActivity.java
│ ├── TaskGang.java
│ ├── filters
│ ├── Filter.java
│ ├── FilterDecorator.java
│ ├── GrayScaleFilter.java
│ ├── NullFilter.java
│ └── OutputFilterDecorator.java
│ └── servermodel
│ ├── FilterData.java
│ ├── ImageData.java
│ ├── ImageStreamService.java
│ └── ServerResponse.java
├── ImageTaskGangConsole
├── .classpath
├── .project
├── DownloadImages
│ ├── GrayScaleFilter
│ │ ├── douglass.jpg
│ │ ├── ironbound.jpg
│ │ ├── ka.png
│ │ ├── lil-doug.jpg
│ │ ├── uci.png
│ │ └── wm.jpg
│ └── NullFilter
│ │ ├── douglass.jpg
│ │ ├── ironbound.jpg
│ │ ├── ka.png
│ │ ├── lil-doug.jpg
│ │ ├── uci.png
│ │ └── wm.jpg
└── src
│ └── example
│ └── imagetaskgang
│ ├── BufferedImage.java
│ ├── Filter.java
│ ├── FilterDecorator.java
│ ├── GrayScaleFilter.java
│ ├── Image.java
│ ├── ImageEntity.java
│ ├── ImageTaskGang.java
│ ├── MainConsole.java
│ ├── NullFilter.java
│ ├── Options.java
│ ├── OutputFilterDecorator.java
│ ├── PlatformStrategy.java
│ ├── PlatformStrategyConsole.java
│ ├── PlatformStrategyFactory.java
│ └── TaskGang.java
├── PingPongWrong
├── .classpath
├── .project
└── src
│ └── PingPongWrong.java
├── SearchTaskGang
├── .classpath
├── .project
└── src
│ ├── OneShotExecutorCompletionService.java
│ ├── OneShotExecutorService.java
│ ├── OneShotExecutorServiceFuture.java
│ ├── OneShotThreadPerTask.java
│ ├── SearchResults.java
│ ├── SearchTaskGangCommon.java
│ ├── TaskGang.java
│ └── TaskGangTest.java
├── SimpleBlockingQueue
├── .classpath
├── .project
└── src
│ ├── SimpleBlockingQueue.java
│ └── SimpleBlockingQueueTest.java
├── TaskGang
├── .classpath
├── .project
└── src
│ ├── CyclicExecutorService.java
│ ├── OneShotExecutorCompletionService.java
│ ├── OneShotExecutorService.java
│ ├── OneShotExecutorServiceFuture.java
│ ├── OneShotThreadPerTask.java
│ ├── SearchResults.java
│ ├── SearchTaskGangCommon.java
│ ├── TaskGang.java
│ └── TaskGangTest.java
├── ThreadGang
├── .classpath
├── .project
└── src
│ ├── ThreadGang.java
│ ├── ThreadGangTest.java
│ └── ThreadJoinTest.java
├── ThreadedDownloads
├── .classpath
├── .project
├── .settings
│ └── org.eclipse.jdt.core.prefs
├── AndroidManifest.xml
├── gen
│ └── edu
│ │ └── vuum
│ │ └── mocca
│ │ ├── BuildConfig.java
│ │ └── R.java
├── project.properties
├── res
│ ├── drawable-hdpi
│ │ ├── default_image.png
│ │ ├── ic_action_search.png
│ │ └── ic_launcher.png
│ ├── drawable-ldpi
│ │ ├── ic_icon.png
│ │ └── ic_launcher.png
│ ├── drawable-mdpi
│ │ ├── default_image.png
│ │ ├── ic_action_search.png
│ │ └── ic_launcher.png
│ ├── drawable-xhdpi
│ │ ├── default_image.png
│ │ ├── ic_action_search.png
│ │ └── ic_launcher.png
│ ├── layout
│ │ └── main.xml
│ ├── menu
│ │ └── options.xml
│ ├── values-v11
│ │ └── styles.xml
│ ├── values-v14
│ │ └── styles.xml
│ └── values
│ │ ├── strings.xml
│ │ └── styles.xml
└── src
│ └── edu
│ └── vuum
│ └── mocca
│ ├── ButtonStrategy.java
│ ├── ButtonStrategyMapper.java
│ ├── DownloadContext.java
│ ├── DownloadWithAsyncTask.java
│ ├── DownloadWithMessages.java
│ ├── DownloadWithRunnable.java
│ ├── ResetImage.java
│ └── ThreadedDownloadsActivity.java
├── UserOrDaemonExecutor
├── .classpath
├── .project
└── src
│ ├── GCDRunnable.java
│ └── TestExecutor.java
├── UserOrDaemonRunnable
├── .classpath
├── .project
└── src
│ ├── GCDRunnable.java
│ └── TestRunnable.java
├── UserOrDaemonThread
├── .classpath
├── .project
└── src
│ ├── TestThread.java
│ └── UserOrDaemonThread.java
├── UserThreadInterrupted
├── .classpath
├── .project
└── src
│ ├── CompletionStage.java
│ ├── GCDRunnable.java
│ ├── RunnableFuture.java
│ ├── TestInterrupted.java
│ └── foo.ucls
└── WeekendPlanner
├── .gitignore
├── Android
├── .classpath
├── .project
├── AndroidManifest.xml
├── ic_launcher-web.png
├── libs
│ ├── android-support-v4.jar
│ ├── gson-2.3.1.jar
│ ├── okhttp-2.4.0.jar
│ ├── okio-1.4.0.jar
│ └── retrofit-1.9.0.jar
├── proguard-project.txt
├── project.properties
├── res
│ ├── drawable-hdpi
│ │ └── ic_launcher.png
│ ├── drawable-mdpi
│ │ └── ic_launcher.png
│ ├── drawable-xhdpi
│ │ └── ic_launcher.png
│ ├── drawable-xxhdpi
│ │ └── ic_launcher.png
│ ├── layout
│ │ ├── activity_main.xml
│ │ ├── fragment_main.xml
│ │ ├── fragment_results.xml
│ │ ├── fragment_tripdetail.xml
│ │ ├── row_basicstring.xml
│ │ ├── row_day.xml
│ │ └── row_tripvariant.xml
│ ├── menu
│ │ └── main.xml
│ ├── values-v11
│ │ └── styles.xml
│ ├── values-v14
│ │ └── styles.xml
│ ├── values-w820dp
│ │ └── dimens.xml
│ └── values
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ └── styles.xml
└── src
│ └── example
│ ├── fragments
│ ├── PromptFragment.java
│ ├── ResultsFragment.java
│ └── TripDetailFragment.java
│ ├── web
│ ├── model
│ │ ├── City.java
│ │ ├── Event.java
│ │ ├── Flight.java
│ │ ├── Geocode.java
│ │ ├── Place.java
│ │ ├── TripVariant.java
│ │ └── Weather.java
│ ├── requests
│ │ └── WeekendPlannerRequest.java
│ ├── responses
│ │ ├── CityResponse.java
│ │ └── WeekendPlannerResponse.java
│ ├── services
│ │ └── WeekendPlannerService.java
│ └── utils
│ │ └── RetrofitAdapterUtils.java
│ └── weekendizer
│ └── MainActivity.java
└── Server
├── .classpath
├── .project
├── WebContent
├── META-INF
│ └── MANIFEST.MF
└── WEB-INF
│ └── lib
│ ├── gson-2.3.1.jar
│ └── retrofit-1.9.0.jar
└── src
└── example
├── web
├── model
│ ├── City.java
│ ├── Event.java
│ ├── Flight.java
│ ├── Geocode.java
│ ├── Place.java
│ ├── TripVariant.java
│ └── Weather.java
├── ops
│ ├── BaseOps.java
│ ├── FlightOps.java
│ ├── PlacesOps.java
│ ├── TicketOps.java
│ └── WeatherOps.java
├── requests
│ └── WeekendPlannerRequest.java
├── responses
│ ├── CityResponse.java
│ ├── FlightResponse.java
│ ├── GeoCodeResponse.java
│ ├── OAuth2TokenResponse.java
│ ├── PlacesResponse.java
│ ├── TicketResponse.java
│ └── WeatherResponse.java
├── services
│ ├── FlightService.java
│ ├── PlacesService.java
│ ├── TicketService.java
│ └── WeatherService.java
└── utils
│ ├── BaseOAuth2Utils.java
│ ├── DateUtils.java
│ ├── FlightAuthUtils.java
│ ├── NoAuthUtils.java
│ ├── PlacesAuthUtils.java
│ └── TicketAuthUtils.java
└── weekendplanner
├── WeekendPlannerOps.java
├── WeekendPlannerResponse.java
└── WeekendPlannerServlet.java
/.gitignore:
--------------------------------------------------------------------------------
1 | #############################################################################
2 | #
3 | # .gitignore declares what files should be ignored by git
4 | #
5 | # This particular file is a composite of github's Android and Eclipse
6 | # files, along with some custom additions.
7 | #
8 | #############################################################################
9 |
10 | #############################################################################
11 | # Eclipse related files
12 | #############################################################################
13 |
14 | *.pydevproject
15 | .metadata
16 | .gradle
17 | bin/
18 | tmp/
19 | *.tmp
20 | *.bak
21 | *.swp
22 | *~.nib
23 | local.properties
24 | .settings/
25 | .loadpath
26 |
27 | # External tool builders
28 | .externalToolBuilders/
29 |
30 | # Locally stored "Eclipse launch configurations"
31 | *.launch
32 |
33 | # CDT-specific
34 | .cproject
35 |
36 | # PDT-specific
37 | .buildpath
38 |
39 | # sbteclipse plugin
40 | .target
41 |
42 | # TeXlipse plugin
43 | .texlipse
44 |
45 | #############################################################################
46 | # Android related files
47 | #############################################################################
48 |
49 | # Built application files
50 | #*.apk
51 | #*.ap_
52 |
53 | # Files for the Dalvik VM
54 | *.dex
55 |
56 | # Java class files
57 | *.class
58 |
59 | # Generated files
60 | bin/
61 | gen/
62 |
63 | # Gradle files
64 | .gradle/
65 | build/
66 |
67 | # Local configuration file (sdk path, etc)
68 | local.properties
69 |
70 | # Proguard folder generated by Eclipse
71 | proguard/
72 |
73 | #Log Files
74 | *.log
75 |
76 | #############################################################################
77 | # Other Misc. files
78 | #############################################################################
79 |
80 | # Temp files for KDE and other Editor's
81 | *~
82 |
83 |
--------------------------------------------------------------------------------
/ex/BarrierTaskGang/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/ex/BarrierTaskGang/.gitignore:
--------------------------------------------------------------------------------
1 | /bin/
2 |
--------------------------------------------------------------------------------
/ex/BarrierTaskGang/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | BarrierTaskGang
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 |
15 | org.eclipse.jdt.core.javanature
16 |
17 |
18 |
--------------------------------------------------------------------------------
/ex/BarrierTaskGang/src/OneShotSearchWithCountDownLatch.java:
--------------------------------------------------------------------------------
1 | import java.util.concurrent.CountDownLatch;
2 |
3 | /**
4 | * @class OneShotSearchWithCountDownLatch
5 | *
6 | * @brief Customizes the SearchTaskGangCommon framework to spawn a
7 | * Thread for each element in the List of input Strings and
8 | * use a CountDownLatch to wait for all the Threads to
9 | * finish concurrently searching the input for an array of
10 | * words to find. It only runs for a single iteration cycle.
11 | */
12 | public class OneShotSearchWithCountDownLatch
13 | extends SearchTaskGangCommon {
14 | /**
15 | * Constructor initializes the super class.
16 | */
17 | OneShotSearchWithCountDownLatch(String[] wordsToFind,
18 | String[][] stringsToSearch) {
19 | // Pass input to superclass constructor.
20 | super(wordsToFind,
21 | stringsToSearch);
22 | }
23 |
24 | /**
25 | * Hook method invoked by initiateTaskGang() to perform custom
26 | * initializations before the Threads in the gang are spawned.
27 | */
28 | @Override
29 | protected void initiateHook(int size) {
30 | BarrierTaskGangTest.printDebugging
31 | ("@@@@@ Started cycle 1 with "
32 | + size
33 | + " Thread"
34 | + (size == 1 ? "" : "s")
35 | + " @@@@@");
36 |
37 | // Create a CountDownLatch whose count corresponds to each
38 | // Thread and element in the input List (which have the same
39 | // value since this model is "Thread-per-input-element").
40 | mExitBarrier = new CountDownLatch(size);
41 | }
42 |
43 | /**
44 | * Hook method called when a worker Thread is done.
45 | */
46 | @Override
47 | protected void taskDone(int index) throws IndexOutOfBoundsException {
48 | // Decrement the CountDownLatch by one. When the count
49 | // reaches 0 the main Thread is released from its call to
50 | // await().
51 | mExitBarrier.countDown();
52 | }
53 | }
54 |
55 |
--------------------------------------------------------------------------------
/ex/BarrierTaskGang/src/SearchTaskGangCommonCyclic.java:
--------------------------------------------------------------------------------
1 | import java.util.concurrent.CountDownLatch;
2 |
3 | /**
4 | * @class SearchTaskGangCommonCyclic
5 | *
6 | * @brief This helper class extends SearchTaskGangCommon and factors
7 | * out the common code used by the cyclic TaskGang
8 | * implementations.
9 | */
10 | public abstract class SearchTaskGangCommonCyclic
11 | extends SearchTaskGangCommon {
12 | /**
13 | * Constructor initializes the data members.
14 | */
15 | protected SearchTaskGangCommonCyclic(String[] wordsToFind,
16 | String[][] stringsToSearch) {
17 | // Pass input to superclass constructor.
18 | super (wordsToFind,
19 | stringsToSearch);
20 |
21 | // Initialize the exit barrier to 1, which causes
22 | // awaitTasksDone() hook method to block until the test is
23 | // finished.
24 | mExitBarrier = new CountDownLatch(1);
25 | }
26 |
27 | /**
28 | * When there's no more input data to process release the exit
29 | * latch and return false so the worker Thread will return.
30 | * Otherwise, return true so the worker Thread will continue
31 | * to run.
32 | */
33 | @Override
34 | protected boolean advanceTaskToNextCycle() {
35 | if (getInput() == null) {
36 | mExitBarrier.countDown();
37 | return false;
38 | } else
39 | return true;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/ex/BuggyQueue/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/ex/BuggyQueue/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | BuggyQueue
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 |
15 | org.eclipse.jdt.core.javanature
16 |
17 |
18 |
--------------------------------------------------------------------------------
/ex/DeadlockQueue/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/ex/DeadlockQueue/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | DeadlockQueue
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 |
15 | org.eclipse.jdt.core.javanature
16 |
17 |
18 |
--------------------------------------------------------------------------------
/ex/DownloadApplication/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/ex/DownloadApplication/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | DownloadApplication
4 |
5 |
6 |
7 |
8 |
9 | com.android.ide.eclipse.adt.ResourceManagerBuilder
10 |
11 |
12 |
13 |
14 | com.android.ide.eclipse.adt.PreCompilerBuilder
15 |
16 |
17 |
18 |
19 | org.eclipse.jdt.core.javabuilder
20 |
21 |
22 |
23 |
24 | com.android.ide.eclipse.adt.ApkBuilder
25 |
26 |
27 |
28 |
29 |
30 | com.android.ide.eclipse.adt.AndroidNature
31 | org.eclipse.jdt.core.javanature
32 |
33 |
34 |
--------------------------------------------------------------------------------
/ex/DownloadApplication/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
12 |
13 |
14 |
19 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/ex/DownloadApplication/gen/edu/vuum/mocca/BuildConfig.java:
--------------------------------------------------------------------------------
1 | /** Automatically generated file. DO NOT MODIFY */
2 | package edu.vuum.mocca;
3 |
4 | public final class BuildConfig {
5 | public final static boolean DEBUG = true;
6 | }
--------------------------------------------------------------------------------
/ex/DownloadApplication/gen/edu/vuum/mocca/R.java:
--------------------------------------------------------------------------------
1 | /* AUTO-GENERATED FILE. DO NOT MODIFY.
2 | *
3 | * This class was automatically generated by the
4 | * aapt tool from the resource data it found. It
5 | * should not be modified by hand.
6 | */
7 |
8 | package edu.vuum.mocca;
9 |
10 | public final class R {
11 | public static final class attr {
12 | }
13 | public static final class drawable {
14 | public static final int default_image=0x7f020000;
15 | public static final int ic_action_search=0x7f020001;
16 | public static final int ic_icon=0x7f020002;
17 | public static final int ic_launcher=0x7f020003;
18 | }
19 | public static final class id {
20 | public static final int about=0x7f070005;
21 | public static final int button1=0x7f070001;
22 | public static final int button2=0x7f070002;
23 | public static final int help=0x7f070004;
24 | public static final int mImageView=0x7f070003;
25 | public static final int mUrlEditText=0x7f070000;
26 | }
27 | public static final class layout {
28 | public static final int main=0x7f030000;
29 | }
30 | public static final class menu {
31 | public static final int options=0x7f060000;
32 | }
33 | public static final class string {
34 | public static final int about=0x7f040007;
35 | public static final int app_name=0x7f040000;
36 | public static final int defaultURL=0x7f040004;
37 | public static final int download=0x7f040002;
38 | public static final int help=0x7f040006;
39 | public static final int location=0x7f040005;
40 | public static final int resetImage=0x7f040003;
41 | public static final int title_activity_download=0x7f040001;
42 | }
43 | public static final class style {
44 | public static final int AppTheme=0x7f050000;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/ex/DownloadApplication/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system edit
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 | #
10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
12 |
13 | # Project target.
14 | target=android-17
15 |
16 |
--------------------------------------------------------------------------------
/ex/DownloadApplication/res/drawable-hdpi/default_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/DownloadApplication/res/drawable-hdpi/default_image.png
--------------------------------------------------------------------------------
/ex/DownloadApplication/res/drawable-hdpi/ic_action_search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/DownloadApplication/res/drawable-hdpi/ic_action_search.png
--------------------------------------------------------------------------------
/ex/DownloadApplication/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/DownloadApplication/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ex/DownloadApplication/res/drawable-ldpi/ic_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/DownloadApplication/res/drawable-ldpi/ic_icon.png
--------------------------------------------------------------------------------
/ex/DownloadApplication/res/drawable-ldpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/DownloadApplication/res/drawable-ldpi/ic_launcher.png
--------------------------------------------------------------------------------
/ex/DownloadApplication/res/drawable-mdpi/default_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/DownloadApplication/res/drawable-mdpi/default_image.png
--------------------------------------------------------------------------------
/ex/DownloadApplication/res/drawable-mdpi/ic_action_search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/DownloadApplication/res/drawable-mdpi/ic_action_search.png
--------------------------------------------------------------------------------
/ex/DownloadApplication/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/DownloadApplication/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ex/DownloadApplication/res/drawable-xhdpi/default_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/DownloadApplication/res/drawable-xhdpi/default_image.png
--------------------------------------------------------------------------------
/ex/DownloadApplication/res/drawable-xhdpi/ic_action_search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/DownloadApplication/res/drawable-xhdpi/ic_action_search.png
--------------------------------------------------------------------------------
/ex/DownloadApplication/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/DownloadApplication/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ex/DownloadApplication/res/layout/main.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
11 |
12 |
18 |
19 |
25 |
26 |
27 |
32 |
33 |
40 |
41 |
48 |
49 |
50 |
51 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/ex/DownloadApplication/res/layout/main.xml.~1~:
--------------------------------------------------------------------------------
1 |
6 |
7 |
11 |
12 |
18 |
19 |
25 |
26 |
27 |
32 |
33 |
40 |
41 |
48 |
49 |
50 |
51 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/ex/DownloadApplication/res/menu/options.xml:
--------------------------------------------------------------------------------
1 |
11 |
--------------------------------------------------------------------------------
/ex/DownloadApplication/res/values-v11/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/ex/DownloadApplication/res/values-v14/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/ex/DownloadApplication/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | DownloadApplication
4 | Download
5 | Download Image
6 | Reset Image
7 | http://www.dre.vanderbilt.edu/~schmidt/ka.png
8 | Enter URL:
9 | Help
10 | About
11 |
12 |
--------------------------------------------------------------------------------
/ex/DownloadApplication/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/ex/ImageStream/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/ex/ImageStream/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | ImageStream
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 |
15 | org.eclipse.jdt.core.javanature
16 |
17 |
18 |
--------------------------------------------------------------------------------
/ex/ImageStream/DownloadImages/GrayScaleFilter/douglass.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/ImageStream/DownloadImages/GrayScaleFilter/douglass.jpg
--------------------------------------------------------------------------------
/ex/ImageStream/DownloadImages/GrayScaleFilter/ironbound.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/ImageStream/DownloadImages/GrayScaleFilter/ironbound.jpg
--------------------------------------------------------------------------------
/ex/ImageStream/DownloadImages/GrayScaleFilter/ka.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/ImageStream/DownloadImages/GrayScaleFilter/ka.png
--------------------------------------------------------------------------------
/ex/ImageStream/DownloadImages/GrayScaleFilter/lil-doug.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/ImageStream/DownloadImages/GrayScaleFilter/lil-doug.jpg
--------------------------------------------------------------------------------
/ex/ImageStream/DownloadImages/GrayScaleFilter/uci.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/ImageStream/DownloadImages/GrayScaleFilter/uci.png
--------------------------------------------------------------------------------
/ex/ImageStream/DownloadImages/GrayScaleFilter/wm.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/ImageStream/DownloadImages/GrayScaleFilter/wm.jpg
--------------------------------------------------------------------------------
/ex/ImageStream/DownloadImages/NullFilter/douglass.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/ImageStream/DownloadImages/NullFilter/douglass.jpg
--------------------------------------------------------------------------------
/ex/ImageStream/DownloadImages/NullFilter/ironbound.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/ImageStream/DownloadImages/NullFilter/ironbound.jpg
--------------------------------------------------------------------------------
/ex/ImageStream/DownloadImages/NullFilter/ka.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/ImageStream/DownloadImages/NullFilter/ka.png
--------------------------------------------------------------------------------
/ex/ImageStream/DownloadImages/NullFilter/lil-doug.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/ImageStream/DownloadImages/NullFilter/lil-doug.jpg
--------------------------------------------------------------------------------
/ex/ImageStream/DownloadImages/NullFilter/uci.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/ImageStream/DownloadImages/NullFilter/uci.png
--------------------------------------------------------------------------------
/ex/ImageStream/DownloadImages/NullFilter/wm.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/ImageStream/DownloadImages/NullFilter/wm.jpg
--------------------------------------------------------------------------------
/ex/ImageStream/src/example/imagestream/BufferedImage.java:
--------------------------------------------------------------------------------
1 | package example.imagestream;
2 |
3 | import java.io.ByteArrayInputStream;
4 | import java.io.IOException;
5 |
6 | import javax.imageio.ImageIO;
7 |
8 | /**
9 | * @class BufferedImage
10 | *
11 | * @brief Encapsulates the Java BufferedImage class via a
12 | * platform-independent interface.
13 | */
14 | class BufferedImage implements Image {
15 | /**
16 | * A Java BufferedImage object.
17 | */
18 | public java.awt.image.BufferedImage mBufferedImage;
19 |
20 | /**
21 | * Constructor that converts an @a imageData of raw bytes into a
22 | * Java @a BufferedImage.
23 | */
24 | public BufferedImage(byte[] imageData) {
25 | try {
26 | mBufferedImage = ImageIO.read(new ByteArrayInputStream(imageData));
27 | } catch (IOException e) {
28 | e.printStackTrace();
29 | }
30 | }
31 |
32 | /**
33 | * Constructor that stores the @a bufferedInmage parameter into
34 | * the data member.
35 | */
36 | public BufferedImage (Object bufferedImage) {
37 | mBufferedImage = (java.awt.image.BufferedImage) bufferedImage;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/ex/ImageStream/src/example/imagestream/Filter.java:
--------------------------------------------------------------------------------
1 | package example.imagestream;
2 |
3 | /**
4 | * @class Filter
5 | *
6 | * @brief An abstract class that defines a means to apply filtering
7 | * operations to an Image. It has a name and an abstract Filter
8 | * method whose implementation must be overridden by a
9 | * subclass. Plays the role of the "Abstract Class" in the
10 | * Template Method pattern and the role of the "Component" in
11 | * the Decorator pattern.
12 | */
13 | public abstract class Filter {
14 | /**
15 | * The name of the filter. Defaults to the Canonical Name of the
16 | * derived filter.
17 | */
18 | protected String mName;
19 |
20 | /**
21 | * Constructs the filter with the default name.
22 | */
23 | public Filter() {
24 | String baseName = this.getClass().getCanonicalName();
25 | mName = baseName.substring(baseName.lastIndexOf(".") + 1);
26 | }
27 |
28 | /**
29 | * Constructs the filter with a custom name.
30 | */
31 | public Filter(String name) {
32 | mName = name;
33 | }
34 |
35 | /**
36 | * Sets the name of the filter.
37 | */
38 | public void setName(String name) {
39 | mName = name;
40 | }
41 |
42 | /**
43 | * Gets the name of the filter.
44 | */
45 | public String getName() {
46 | return mName;
47 | }
48 |
49 | /**
50 | * This template method calls the applyFilter() hook method (which
51 | * must be defined by a subclass) to filter the @a imageEntity
52 | * parameter and sets the filterName of the result to the name of
53 | * the filter.
54 | */
55 | public ImageEntity filter(ImageEntity imageEntity) {
56 | // Call the applyFilter() hook method.
57 | ImageEntity filteredResult = applyFilter(imageEntity);
58 | filteredResult.setFilterName(this);
59 | return filteredResult;
60 | }
61 |
62 | /**
63 | * This abstract hook method must be overridden by a subclass to
64 | * define the logic for processing the given @a imageEntity.
65 | */
66 | protected abstract ImageEntity applyFilter(ImageEntity imageEntity);
67 | }
68 |
--------------------------------------------------------------------------------
/ex/ImageStream/src/example/imagestream/FilterDecorator.java:
--------------------------------------------------------------------------------
1 | package example.imagestream;
2 |
3 | /**
4 | * @class FilterDecorator
5 | *
6 | * @brief Allows the addition of behavior to an object dynamically
7 | * without affecting the behavior of other objects from the
8 | * same class. Plays the role of the "Decorator" in the
9 | * Decorator pattern.
10 | */
11 | public abstract class FilterDecorator extends Filter {
12 | /**
13 | * The Filter that's being decorated.
14 | */
15 | protected Filter mFilter;
16 |
17 | /**
18 | * Constructor initializes superclass and data member with the
19 | * given @a filter.
20 | */
21 | public FilterDecorator(Filter filter) {
22 | super(filter.getName());
23 | mFilter = filter;
24 | }
25 |
26 | /**
27 | * This hook method forwards to the decorated filter to filter the
28 | * @a imageEntity parameter.
29 | */
30 | @Override
31 | protected ImageEntity applyFilter(ImageEntity imageEntity) {
32 | return decorate(mFilter.filter(imageEntity));
33 | }
34 |
35 | /**
36 | * An abstract hook method that "decorates" the data member
37 | * filter, which is applied to the imageEntity after it's been
38 | * filtered.
39 | */
40 | protected abstract ImageEntity decorate(ImageEntity imageEntity);
41 | }
42 |
--------------------------------------------------------------------------------
/ex/ImageStream/src/example/imagestream/GrayScaleFilter.java:
--------------------------------------------------------------------------------
1 | package example.imagestream;
2 |
3 | /**
4 | * @class Filter
5 | *
6 | * @brief A Filter sublcass that converts a downloaded image to
7 | * grayscale.
8 | */
9 | public class GrayScaleFilter extends Filter {
10 | /**
11 | * Constructs a default GrayScaleFilter.
12 | */
13 | public GrayScaleFilter() {}
14 |
15 | /**
16 | * Constructs a Grayscale filter with the given name. This
17 | * constructor can be used to specify the output directory the
18 | * grayscale filtered images should be stored in. This naming
19 | * functionality would also be useful for filters to which
20 | * parameters are passed. For example, a 5x5 box filter and a 3x3
21 | * box filter could reuse identical code, but be stored in
22 | * different directories after processing.
23 | */
24 | public GrayScaleFilter(String name) {
25 | super(name);
26 | }
27 |
28 | /**
29 | * Uses the common color transformation values for grayscale
30 | * conversion using a pixel-by-pixel coloring algorithm.
31 | */
32 | @Override
33 | protected ImageEntity applyFilter(ImageEntity imageEntity) {
34 | // Forward to the platform-specific implementation of this
35 | // filter.
36 | return PlatformStrategy.instance().grayScaleFilter(imageEntity);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/ex/ImageStream/src/example/imagestream/Image.java:
--------------------------------------------------------------------------------
1 | package example.imagestream;
2 |
3 | /**
4 | * @class Image
5 | *
6 | * @brief Defines a platform-independent Image interface, which can be
7 | * implemented for different runtime environments, e.g.,
8 | * Android or plain Java.
9 | */
10 | interface Image {
11 | }
12 |
--------------------------------------------------------------------------------
/ex/ImageStream/src/example/imagestream/ImageStreamParallel.java:
--------------------------------------------------------------------------------
1 | package example.imagestream;
2 |
3 | import java.net.URL;
4 | import java.util.Iterator;
5 | import java.util.List;
6 | import java.util.concurrent.CountDownLatch;
7 |
8 | /**
9 | * @class ImageStreamParallel
10 | *
11 | * @brief Customizes ImageStream to use a Java 8 stream to download,
12 | * process, and store images concurrently.
13 | */
14 | public class ImageStreamParallel extends ImageStream {
15 | /**
16 | * Constructor initializes the superclass and data members.
17 | */
18 | public ImageStreamParallel(Filter[] filters,
19 | Iterator> urlListIterator,
20 | Runnable completionHook) {
21 | super(filters, urlListIterator, completionHook);
22 | }
23 |
24 | /**
25 | * Initiate the ImageStream processing, which uses a Java 8 stream
26 | * to download, process, and store images concurrently.
27 | */
28 | @Override
29 | protected void initiateStream() {
30 | // Create a new exit barrier.
31 | mIterationBarrier = new CountDownLatch(1);
32 |
33 | // Concurrently process each filter in the mFilters List.
34 | mFilters.parallelStream()
35 | .forEach(filter -> {
36 | List urls = getInput();
37 | // Use Java 8 streams to download and filter all
38 | // urls concurrently.
39 | urls.parallelStream()
40 | // Call processInput() to download and filter
41 | // the image retrieved from the given URL,
42 | // store the results in a file, and indicate
43 | // success or failure.
44 | .map(url -> processInput(url, filter))
45 | .forEach(image ->
46 | // Indicate success or failure.
47 | PlatformStrategy.instance().errorLog
48 | ("ImageStreamParallel",
49 | "Operations"
50 | + (image.getSucceeded() == true
51 | ? " succeeded"
52 | : " failed")
53 | + " on file "
54 | + image.getSourceURL())
55 | );
56 | });
57 |
58 | // Indicate all computations in this iteration are done.
59 | try {
60 | mIterationBarrier.countDown();
61 | } catch (Exception ex) {
62 | throw new RuntimeException(ex);
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/ex/ImageStream/src/example/imagestream/ImageStreamSequential.java:
--------------------------------------------------------------------------------
1 | package example.imagestream;
2 |
3 | import java.net.URL;
4 | import java.util.Iterator;
5 | import java.util.List;
6 | import java.util.concurrent.CountDownLatch;
7 |
8 | /**
9 | * @class ImageStreamSequential
10 | *
11 | * @brief Customizes ImageStream to use a Java 8 stream to download,
12 | * process, and store images sequentially.
13 | */
14 | public class ImageStreamSequential extends ImageStream {
15 | /**
16 | * Constructor initializes the superclass and data members.
17 | */
18 | public ImageStreamSequential(Filter[] filters,
19 | Iterator> urlListIterator,
20 | Runnable completionHook) {
21 | super(filters, urlListIterator, completionHook);
22 | }
23 |
24 | /**
25 | * Initiate the ImageStream processing, which uses a Java 8 stream
26 | * to download, process, and store images sequentially.
27 | */
28 | @Override
29 | protected void initiateStream() {
30 | // Create a new barrier for this iteration cycle.
31 | mIterationBarrier = new CountDownLatch(1);
32 |
33 | // Sequentially process each filter in the mFilters List.
34 | mFilters.forEach
35 | (filter -> {
36 | List urls = getInput();
37 | // Use Java 8 streams to download and filter all urls
38 | // sequentially.
39 | urls.stream()
40 | // Call processInput() to download and filter the
41 | // image retrieved from the given URL, store the
42 | // results in a file, and indicate success or
43 | // failure.
44 | .map(url -> processInput(url, filter))
45 | .forEach(image ->
46 | // Indicate success or failure.
47 | PlatformStrategy.instance().errorLog
48 | ("ImageStreamSequential",
49 | "Operations"
50 | + (image.getSucceeded() == true
51 | ? " succeeded"
52 | : " failed")
53 | + " on file "
54 | + image.getSourceURL())
55 | );
56 | });
57 |
58 | // Indicate all computations in this iteration are done.
59 | try {
60 | mIterationBarrier.countDown();
61 | } catch (Exception ex) {
62 | throw new RuntimeException(ex);
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/ex/ImageStream/src/example/imagestream/NullFilter.java:
--------------------------------------------------------------------------------
1 | package example.imagestream;
2 |
3 | /**
4 | * @class NullFilter
5 | *
6 | * @brief The NullFilter will return the image as it was downloaded.
7 | * It's main purpose is to show the "Control" image, and to
8 | * exemplify how filters are supposed to work on a basic level.
9 | */
10 | public class NullFilter extends Filter {
11 | /**
12 | * Default constructor is a no-op.
13 | */
14 | public NullFilter() {}
15 |
16 | /**
17 | * Constructors for the NullFilter. See GrayScaleFilter for
18 | * explanation of filter naming.
19 | */
20 | public NullFilter(String name) {
21 | super(name);
22 | }
23 |
24 | /**
25 | * Constructs a new ImageEntity that does not change the original
26 | * at all.
27 | */
28 | @Override
29 | protected ImageEntity applyFilter(ImageEntity imageEntity) {
30 | return imageEntity;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/ex/ImageStream/src/example/imagestream/OutputFilterDecorator.java:
--------------------------------------------------------------------------------
1 | package example.imagestream;
2 |
3 | import java.io.File;
4 | import java.io.FileOutputStream;
5 |
6 | /**
7 | * @class OutputFilterDecorator
8 | *
9 | * @brief A Decorator that applies the filter passed to its
10 | * constructor and then writes the results to an output file.
11 | * Plays the role of the "Concrete Decorator" in the Decorator
12 | * pattern.
13 | */
14 | public class OutputFilterDecorator extends FilterDecorator {
15 | /**
16 | * Constructs the filter decorator with the @a filter to apply.
17 | */
18 | public OutputFilterDecorator(Filter filter) {
19 | super(filter);
20 | }
21 |
22 | /**
23 | * The hook method that is called on the ImageEntity once it has
24 | * been filtered with mFilter. This method stores the filtered
25 | * ImageEntity in a file by delegating the storing to the
26 | * platform- specific implementation of storeImage(...).
27 | */
28 | @Override
29 | protected ImageEntity decorate(ImageEntity imageEntity) {
30 | if (true) {
31 | // Call the applyFilter() hook method.
32 | ImageEntity result = (ImageEntity) imageEntity;
33 |
34 | // Make a directory for the filter if it does not already
35 | // exist.
36 | File externalFile =
37 | new File(PlatformStrategy.instance().getDirectoryPath(),
38 | this.getName());
39 | externalFile.mkdirs();
40 |
41 | // We will store the filtered image as its original filename,
42 | // within the appropriate filter directory to organize the
43 | // filtered results.
44 | File newImage =
45 | new File(externalFile,
46 | result.getFileName());
47 |
48 | // Write the compressed image to the appropriate directory.
49 | try (FileOutputStream outputFile = new FileOutputStream(newImage)) {
50 | PlatformStrategy.instance().storeImage(result.getImage(),
51 | outputFile);
52 | } catch (Exception e) {
53 | // Try-with-resources will clean up resources.
54 | e.printStackTrace();
55 | return null;
56 | }
57 |
58 | return result;
59 | } else {
60 | PlatformStrategy.instance().errorLog
61 | ("OutoutFileDecorator",
62 | "sdcard isn't mounted");
63 | return null;
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/ex/ImageStreamWeb/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/ex/ImageStreamWeb/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | ImageStreamWeb
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.wst.jsdt.core.javascriptValidator
10 |
11 |
12 |
13 |
14 | org.eclipse.jdt.core.javabuilder
15 |
16 |
17 |
18 |
19 | org.eclipse.wst.common.project.facet.core.builder
20 |
21 |
22 |
23 |
24 | org.eclipse.wst.validation.validationbuilder
25 |
26 |
27 |
28 |
29 |
30 | org.eclipse.jem.workbench.JavaEMFNature
31 | org.eclipse.wst.common.modulecore.ModuleCoreNature
32 | org.eclipse.wst.common.project.facet.core.nature
33 | org.eclipse.jdt.core.javanature
34 | org.eclipse.wst.jsdt.core.jsNature
35 |
36 |
37 |
--------------------------------------------------------------------------------
/ex/ImageStreamWeb/WebContent/META-INF/MANIFEST.MF:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | Class-Path:
3 |
4 |
--------------------------------------------------------------------------------
/ex/ImageStreamWeb/WebContent/WEB-INF/lib/gson-2.3.1.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/ImageStreamWeb/WebContent/WEB-INF/lib/gson-2.3.1.jar
--------------------------------------------------------------------------------
/ex/ImageStreamWeb/WebContent/WEB-INF/web.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | ImageStreamWeb
4 |
5 | index.html
6 | index.htm
7 | index.jsp
8 | default.html
9 | default.htm
10 | default.jsp
11 |
12 |
--------------------------------------------------------------------------------
/ex/ImageStreamWeb/src/example/BufferedImage.java:
--------------------------------------------------------------------------------
1 | package example;
2 |
3 | import java.io.ByteArrayInputStream;
4 | import java.io.IOException;
5 |
6 | import javax.imageio.ImageIO;
7 |
8 | /**
9 | * @class BufferedImage
10 | *
11 | * @brief Encapsulates the Java BufferedImage class via a
12 | * platform-independent interface.
13 | */
14 | class BufferedImage implements Image {
15 | /**
16 | * A Java BufferedImage object.
17 | */
18 | public java.awt.image.BufferedImage mBufferedImage;
19 |
20 | /**
21 | * Constructor that converts an @a imageData of raw bytes into a
22 | * Java @a BufferedImage.
23 | */
24 | public BufferedImage(byte[] imageData) {
25 | try {
26 | mBufferedImage = ImageIO.read(new ByteArrayInputStream(imageData));
27 | } catch (IOException e) {
28 | e.printStackTrace();
29 | }
30 | }
31 |
32 | /**
33 | * Constructor that stores the @a bufferedInmage parameter into
34 | * the data member.
35 | */
36 | public BufferedImage (Object bufferedImage) {
37 | mBufferedImage = (java.awt.image.BufferedImage) bufferedImage;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/ex/ImageStreamWeb/src/example/Image.java:
--------------------------------------------------------------------------------
1 | package example;
2 |
3 | /**
4 | * @class Image
5 | *
6 | * @brief Defines a platform-independent Image interface, which can be
7 | * implemented for different runtime environments, e.g.,
8 | * Android or plain Java.
9 | */
10 | interface Image {
11 | }
12 |
--------------------------------------------------------------------------------
/ex/ImageStreamWeb/src/example/ImageStreamParallel.java:
--------------------------------------------------------------------------------
1 | package example;
2 |
3 | import java.net.URL;
4 | import java.util.Iterator;
5 | import java.util.List;
6 | import java.util.concurrent.CountDownLatch;
7 |
8 | import filters.Filter;
9 | import filters.OutputFilterDecorator;
10 |
11 | /**
12 | * @class ImageStreamParallel
13 | *
14 | * @brief Customizes ImageStream to use a Java 8 stream to download,
15 | * process, and store images concurrently.
16 | */
17 | public class ImageStreamParallel extends ImageStream {
18 | /**
19 | * Constructor initializes the superclass and data members.
20 | */
21 | public ImageStreamParallel(Filter[] filters,
22 | Iterator> urlListIterator,
23 | Runnable completionHook) {
24 | super(filters, urlListIterator, completionHook);
25 | }
26 |
27 | /**
28 | * Initiate the ImageStream processing, which uses a Java 8 stream
29 | * to download, process, and store images concurrently.
30 | */
31 | @Override
32 | protected void initiateStream() {
33 | // Create a new exit barrier.
34 | mIterationBarrier = new CountDownLatch(1);
35 |
36 | getInput().parallelStream()
37 | // transform URL -> ImageEntity
38 | .map(url -> makeImageEntity(url))
39 | // Check to see if the download was successful
40 | .peek(image ->
41 | PlatformStrategy.instance().errorLog
42 | ("ImageStreamParallel",
43 | "Operations"
44 | + (image.getSucceeded() == true
45 | ? " succeeded"
46 | : " failed")
47 | + " on file "
48 | + image.getSourceURL()))
49 | // collect each image and apply each filter in parallel
50 | .forEach(image -> {
51 | mFilters.parallelStream()
52 | // decorate each filter to write the images to files
53 | .map(filter -> new OutputFilterDecorator(filter))
54 | // filter the image
55 | .forEach(decoratedFilter ->
56 | decoratedFilter.filter(image));
57 | });
58 |
59 | // Indicate all computations in this iteration are done.
60 | try {
61 | mIterationBarrier.countDown();
62 | } catch (Exception ex) {
63 | throw new RuntimeException(ex);
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/ex/ImageStreamWeb/src/example/ImageStreamSequential.java:
--------------------------------------------------------------------------------
1 | package example;
2 |
3 | import java.net.URL;
4 | import java.util.Iterator;
5 | import java.util.List;
6 | import java.util.concurrent.CountDownLatch;
7 |
8 | import filters.Filter;
9 | import filters.OutputFilterDecorator;
10 |
11 | /**
12 | * @class ImageStreamSequential
13 | *
14 | * @brief Customizes ImageStream to use a Java 8 stream to download,
15 | * process, and store images sequentially.
16 | */
17 | public class ImageStreamSequential extends ImageStream {
18 | /**
19 | * Constructor initializes the superclass and data members.
20 | */
21 | public ImageStreamSequential(Filter[] filters,
22 | Iterator> urlListIterator,
23 | Runnable completionHook) {
24 | super(filters, urlListIterator, completionHook);
25 | }
26 |
27 | /**
28 | * Initiate the ImageStream processing, which uses a Java 8 stream
29 | * to download, process, and store images sequentially.
30 | */
31 | @Override
32 | protected void initiateStream() {
33 | // Create a new barrier for this iteration cycle.
34 | mIterationBarrier = new CountDownLatch(1);
35 |
36 | // Sequentially process each filter in the mFilters List.
37 | getInput().stream()
38 | // transform URL -> ImageEntity
39 | .map(url -> makeImageEntity(url))
40 | // Check to see if the download was successful
41 | .peek(image ->
42 | PlatformStrategy.instance().errorLog
43 | ("ImageStreamParallel",
44 | "Operations"
45 | + (image.getSucceeded() == true
46 | ? " succeeded"
47 | : " failed")
48 | + " on file "
49 | + image.getSourceURL()))
50 | // collect each image and apply each filter in parallel
51 | .forEach(image -> {
52 | mFilters.stream()
53 | // decorate each filter to write the images to files
54 | .map(filter -> new OutputFilterDecorator(filter))
55 | // filter the image
56 | .forEach(decoratedFilter ->
57 | decoratedFilter.filter(image));
58 | });
59 |
60 | // Indicate all computations in this iteration are done.
61 | try {
62 | mIterationBarrier.countDown();
63 | } catch (Exception ex) {
64 | throw new RuntimeException(ex);
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/ex/ImageStreamWeb/src/example/PlatformStrategyProxy.java:
--------------------------------------------------------------------------------
1 | package example;
2 |
3 | import java.net.URL;
4 | import java.util.Iterator;
5 | import java.util.List;
6 |
7 | import javax.servlet.ServletContext;
8 |
9 | public class PlatformStrategyProxy extends PlatformStrategyConsole {
10 |
11 | private String mServletTempDir;
12 | private List> mInputURLs;
13 |
14 | public PlatformStrategyProxy(Object output,
15 | ServletContext servletContext,
16 | List> requestUrls) {
17 | super(output);
18 | mServletTempDir = servletContext.getAttribute(
19 | ServletContext.TEMPDIR).toString();
20 | mOutput.println("Writing results to: " + mServletTempDir);
21 | mInputURLs = requestUrls;
22 | }
23 |
24 | @Override
25 | public Iterator> getUrlIterator(InputSource source) {
26 | switch (source) {
27 | case NETWORK:
28 | return mInputURLs.iterator();
29 | default:
30 | mOutput.println("Invalid Source");
31 | return null;
32 | }
33 | }
34 |
35 | @Override
36 | public String getDirectoryPath() {
37 | return mServletTempDir;
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/ex/ImageStreamWeb/src/filters/Filter.java:
--------------------------------------------------------------------------------
1 | package filters;
2 |
3 | import example.ImageEntity;
4 |
5 | /**
6 | * @class Filter
7 | *
8 | * @brief An abstract class that defines a means to apply filtering
9 | * operations to an Image. It has a name and an abstract Filter
10 | * method whose implementation must be overridden by a
11 | * subclass. Plays the role of the "Abstract Class" in the
12 | * Template Method pattern and the role of the "Component" in
13 | * the Decorator pattern.
14 | */
15 | public abstract class Filter {
16 | /**
17 | * The name of the filter. Defaults to the Canonical Name of the
18 | * derived filter.
19 | */
20 | protected String mName;
21 |
22 | /**
23 | * Constructs the filter with the default name.
24 | */
25 | public Filter() {
26 | String baseName = this.getClass().getCanonicalName();
27 | mName = baseName.substring(baseName.lastIndexOf(".") + 1);
28 | }
29 |
30 | /**
31 | * Constructs the filter with a custom name.
32 | */
33 | public Filter(String name) {
34 | mName = name;
35 | }
36 |
37 | /**
38 | * Sets the name of the filter.
39 | */
40 | public void setName(String name) {
41 | mName = name;
42 | }
43 |
44 | /**
45 | * Gets the name of the filter.
46 | */
47 | public String getName() {
48 | return mName;
49 | }
50 |
51 | /**
52 | * This template method calls the applyFilter() hook method (which
53 | * must be defined by a subclass) to filter the @a imageEntity
54 | * parameter and sets the filterName of the result to the name of
55 | * the filter.
56 | */
57 | public ImageEntity filter(ImageEntity imageEntity) {
58 | // Call the applyFilter() hook method.
59 | ImageEntity filteredResult = applyFilter(imageEntity);
60 | filteredResult.setFilterName(this);
61 | return filteredResult;
62 | }
63 |
64 | /**
65 | * This abstract hook method must be overridden by a subclass to
66 | * define the logic for processing the given @a imageEntity.
67 | */
68 | protected abstract ImageEntity applyFilter(ImageEntity imageEntity);
69 | }
70 |
--------------------------------------------------------------------------------
/ex/ImageStreamWeb/src/filters/FilterDecorator.java:
--------------------------------------------------------------------------------
1 | package filters;
2 |
3 | import example.ImageEntity;
4 |
5 | /**
6 | * @class FilterDecorator
7 | *
8 | * @brief Allows the addition of behavior to an object dynamically
9 | * without affecting the behavior of other objects from the
10 | * same class. Plays the role of the "Decorator" in the
11 | * Decorator pattern.
12 | */
13 | public abstract class FilterDecorator extends Filter {
14 | /**
15 | * The Filter that's being decorated.
16 | */
17 | protected Filter mFilter;
18 |
19 | /**
20 | * Constructor initializes superclass and data member with the
21 | * given @a filter.
22 | */
23 | public FilterDecorator(Filter filter) {
24 | super(filter.getName());
25 | mFilter = filter;
26 | }
27 |
28 | /**
29 | * This hook method forwards to the decorated filter to filter the
30 | * @a imageEntity parameter.
31 | */
32 | @Override
33 | protected ImageEntity applyFilter(ImageEntity imageEntity) {
34 | return decorate(mFilter.filter(imageEntity));
35 | }
36 |
37 | /**
38 | * An abstract hook method that "decorates" the data member
39 | * filter, which is applied to the imageEntity after it's been
40 | * filtered.
41 | */
42 | protected abstract ImageEntity decorate(ImageEntity imageEntity);
43 | }
44 |
--------------------------------------------------------------------------------
/ex/ImageStreamWeb/src/filters/GrayScaleFilter.java:
--------------------------------------------------------------------------------
1 | package filters;
2 |
3 | import example.ImageEntity;
4 | import example.PlatformStrategy;
5 |
6 | /**
7 | * @class Filter
8 | *
9 | * @brief A Filter sublcass that converts a downloaded image to
10 | * grayscale.
11 | */
12 | public class GrayScaleFilter extends Filter {
13 | /**
14 | * Constructs a default GrayScaleFilter.
15 | */
16 | public GrayScaleFilter() {}
17 |
18 | /**
19 | * Constructs a Grayscale filter with the given name. This
20 | * constructor can be used to specify the output directory the
21 | * grayscale filtered images should be stored in. This naming
22 | * functionality would also be useful for filters to which
23 | * parameters are passed. For example, a 5x5 box filter and a 3x3
24 | * box filter could reuse identical code, but be stored in
25 | * different directories after processing.
26 | */
27 | public GrayScaleFilter(String name) {
28 | super(name);
29 | }
30 |
31 | /**
32 | * Uses the common color transformation values for grayscale
33 | * conversion using a pixel-by-pixel coloring algorithm.
34 | */
35 | @Override
36 | protected ImageEntity applyFilter(ImageEntity imageEntity) {
37 | // Forward to the platform-specific implementation of this
38 | // filter.
39 | return PlatformStrategy.instance().grayScaleFilter(imageEntity);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/ex/ImageStreamWeb/src/filters/NullFilter.java:
--------------------------------------------------------------------------------
1 | package filters;
2 |
3 | import example.ImageEntity;
4 |
5 | /**
6 | * @class NullFilter
7 | *
8 | * @brief The NullFilter will return the image as it was downloaded.
9 | * It's main purpose is to show the "Control" image, and to
10 | * exemplify how filters are supposed to work on a basic level.
11 | */
12 | public class NullFilter extends Filter {
13 | /**
14 | * Default constructor is a no-op.
15 | */
16 | public NullFilter() {}
17 |
18 | /**
19 | * Constructors for the NullFilter. See GrayScaleFilter for
20 | * explanation of filter naming.
21 | */
22 | public NullFilter(String name) {
23 | super(name);
24 | }
25 |
26 | /**
27 | * Constructs a new ImageEntity that does not change the original
28 | * at all.
29 | */
30 | @Override
31 | protected ImageEntity applyFilter(ImageEntity imageEntity) {
32 | return imageEntity;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/ex/ImageStreamWeb/src/filters/OutputFilterDecorator.java:
--------------------------------------------------------------------------------
1 | package filters;
2 |
3 | import example.ImageEntity;
4 | import example.PlatformStrategy;
5 |
6 | /**
7 | * @class OutputFilterDecorator
8 | *
9 | * @brief A Decorator that applies the filter passed to its
10 | * constructor and then writes the results to an output file.
11 | * Plays the role of the "Concrete Decorator" in the Decorator
12 | * pattern.
13 | */
14 | public class OutputFilterDecorator extends FilterDecorator {
15 | /**
16 | * Constructs the filter decorator with the @a filter to apply.
17 | */
18 | public OutputFilterDecorator(Filter filter) {
19 | super(filter);
20 | }
21 |
22 | /**
23 | * The hook method that is called on the ImageEntity once it has
24 | * been filtered with mFilter. This method stores the filtered
25 | * ImageEntity in a file by delegating the storing to the
26 | * platform- specific implementation of storeImage(...).
27 | */
28 | @Override
29 | protected ImageEntity decorate(ImageEntity imageEntity) {
30 | // Store the filtered image as its filename (which is derived
31 | // from its URL), within the appropriate filter directory to
32 | // organize the filtered results and write the image to
33 | // the file in the appropriate directory.
34 | PlatformStrategy.instance()
35 | .storeExternalImage(this.getName(),
36 | imageEntity.getFileName(),
37 | imageEntity.getImage());
38 |
39 | return imageEntity;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/ex/ImageTaskGang/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/ex/ImageTaskGang/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | ImageTaskGang
4 |
5 |
6 |
7 |
8 |
9 | com.android.ide.eclipse.adt.ResourceManagerBuilder
10 |
11 |
12 |
13 |
14 | com.android.ide.eclipse.adt.PreCompilerBuilder
15 |
16 |
17 |
18 |
19 | org.eclipse.jdt.core.javabuilder
20 |
21 |
22 |
23 |
24 | com.android.ide.eclipse.adt.ApkBuilder
25 |
26 |
27 |
28 |
29 |
30 | com.android.ide.eclipse.adt.AndroidNature
31 | org.eclipse.jdt.core.javanature
32 |
33 |
34 |
--------------------------------------------------------------------------------
/ex/ImageTaskGang/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
13 |
14 |
19 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/ex/ImageTaskGang/libs/META-INF/MANIFEST.MF:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | Archiver-Version: Plexus Archiver
3 | Built-By: jw
4 | Created-By: Apache Maven 3.2.5
5 | Build-Jdk: 1.8.0_25
6 |
7 |
--------------------------------------------------------------------------------
/ex/ImageTaskGang/libs/META-INF/maven/com.squareup.retrofit/retrofit/pom.properties:
--------------------------------------------------------------------------------
1 | #Generated by Maven
2 | #Wed Jan 07 21:36:13 PST 2015
3 | version=1.9.0
4 | groupId=com.squareup.retrofit
5 | artifactId=retrofit
6 |
--------------------------------------------------------------------------------
/ex/ImageTaskGang/libs/META-INF/maven/com.squareup.retrofit/retrofit/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 4.0.0
5 |
6 |
7 | com.squareup.retrofit
8 | parent
9 | 1.9.0
10 | ../pom.xml
11 |
12 |
13 | retrofit
14 | Retrofit
15 |
16 |
17 |
18 | com.google.code.gson
19 | gson
20 |
21 |
22 |
23 | com.google.android
24 | android
25 | true
26 |
27 |
28 | com.squareup.okhttp
29 | okhttp
30 | true
31 |
32 |
33 | io.reactivex
34 | rxjava
35 | true
36 |
37 |
38 | com.google.appengine
39 | appengine-api-1.0-sdk
40 | true
41 |
42 |
43 |
44 | junit
45 | junit
46 | test
47 |
48 |
49 | org.assertj
50 | assertj-core
51 | test
52 |
53 |
54 | org.mockito
55 | mockito-core
56 | test
57 |
58 |
59 | com.google.guava
60 | guava
61 | test
62 |
63 |
64 | com.squareup.okhttp
65 | mockwebserver
66 | test
67 |
68 |
69 |
70 |
71 |
72 |
73 | org.apache.maven.plugins
74 | maven-compiler-plugin
75 |
76 |
77 | -proc:none
78 |
79 |
80 |
81 |
82 |
83 |
--------------------------------------------------------------------------------
/ex/ImageTaskGang/libs/android-support-v4.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/ImageTaskGang/libs/android-support-v4.jar
--------------------------------------------------------------------------------
/ex/ImageTaskGang/libs/gson-2.3.1.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/ImageTaskGang/libs/gson-2.3.1.jar
--------------------------------------------------------------------------------
/ex/ImageTaskGang/libs/retrofit-1.9.0.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/ImageTaskGang/libs/retrofit-1.9.0.jar
--------------------------------------------------------------------------------
/ex/ImageTaskGang/proguard-project.txt:
--------------------------------------------------------------------------------
1 | # To enable ProGuard in your project, edit project.properties
2 | # to define the proguard.config property as described in that file.
3 | #
4 | # Add project specific ProGuard rules here.
5 | # By default, the flags in this file are appended to flags specified
6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt
7 | # You can edit the include path and order by changing the ProGuard
8 | # include property in project.properties.
9 | #
10 | # For more details, see
11 | # http://developer.android.com/guide/developing/tools/proguard.html
12 |
13 | # Add any project specific keep options here:
14 |
15 | # If your project uses WebView with JS, uncomment the following
16 | # and specify the fully qualified class name to the JavaScript interface
17 | # class:
18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
19 | # public *;
20 | #}
21 |
--------------------------------------------------------------------------------
/ex/ImageTaskGang/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system edit
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 | #
10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
12 |
13 | # Project target.
14 | target=android-20
15 |
16 |
--------------------------------------------------------------------------------
/ex/ImageTaskGang/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/ImageTaskGang/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ex/ImageTaskGang/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/ImageTaskGang/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ex/ImageTaskGang/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/ImageTaskGang/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ex/ImageTaskGang/res/layout/activity_result.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
20 |
21 |
22 |
23 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/ex/ImageTaskGang/res/layout/list_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/ex/ImageTaskGang/res/layout/result_button.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
--------------------------------------------------------------------------------
/ex/ImageTaskGang/res/layout/suggestion_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
--------------------------------------------------------------------------------
/ex/ImageTaskGang/res/values-v11/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/ex/ImageTaskGang/res/values-v14/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/ex/ImageTaskGang/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ImageTaskGang
5 | Add URLs
6 | Default (Local)
7 | Default (Server)
8 | List of URLs separated by commas
9 | Run (Local)
10 | Run (Server)
11 | Go Back
12 | A Large View
13 | Clear Downloads
14 | Clear Lists
15 |
16 |
17 |
--------------------------------------------------------------------------------
/ex/ImageTaskGang/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
14 |
15 |
16 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/ex/ImageTaskGang/src/example/imagetaskgang/BufferedImage.java:
--------------------------------------------------------------------------------
1 | package example.imagetaskgang;
2 |
3 | // import javax.imageio.ImageIO;
4 |
5 | /**
6 | * @class BufferedImage
7 | *
8 | * @brief Encapsulates the Java BufferedImage class via a
9 | * platform-independent interface.
10 | */
11 | class BufferedImage implements Image {
12 | /**
13 | * A Java BufferedImage object.
14 | */
15 | // @@ Need to fix
16 | //public java.awt.image.BufferedImage mBufferedImage;
17 |
18 | /**
19 | * Constructor that converts an @a imageData of raw bytes into a
20 | * Java @a BufferedImage.
21 | */
22 | public BufferedImage(byte[] imageData) {
23 | // try {
24 | // mBufferedImage = ImageIO.read(new ByteArrayInputStream(imageData));
25 | // } catch (IOException e) {
26 | // e.printStackTrace();
27 | // }
28 | }
29 |
30 | /**
31 | * Constructor that stores the @a bufferedInmage parameter into
32 | * the data member.
33 | */
34 | public BufferedImage (Object bufferedImage) {
35 | // mBufferedImage = (java.awt.image.BufferedImage) bufferedImage;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/ex/ImageTaskGang/src/example/imagetaskgang/Image.java:
--------------------------------------------------------------------------------
1 | package example.imagetaskgang;
2 |
3 | /**
4 | * @class Image
5 | *
6 | * @brief Defines a platform-independent Image interface, which can be
7 | * implemented for different runtime environments, e.g.,
8 | * Android or plain Java.
9 | */
10 | interface Image {
11 | }
12 |
--------------------------------------------------------------------------------
/ex/ImageTaskGang/src/example/imagetaskgang/filters/Filter.java:
--------------------------------------------------------------------------------
1 | package example.imagetaskgang.filters;
2 |
3 | import example.imagetaskgang.ImageEntity;
4 |
5 | /**
6 | * @class Filter
7 | *
8 | * @brief An abstract class that defines an interface for applying
9 | * filtering operations to an Image. Each Filter has a name and
10 | * an abstract method whose implementation must be overridden
11 | * by a subclass. Plays the role of the "Abstract Class" in
12 | * the Template Method pattern and the role of the "Component"
13 | * in the Decorator pattern.
14 | */
15 | public abstract class Filter {
16 | /**
17 | * The name of the filter, which defaults to the "canonical name"
18 | * of the subclass Filter instance.
19 | */
20 | protected String mName;
21 |
22 | /**
23 | * Constructs the filter with the default name.
24 | */
25 | public Filter() {
26 | String baseName = this.getClass().getCanonicalName();
27 | mName = baseName.substring(baseName.lastIndexOf(".") + 1);
28 | }
29 |
30 | /**
31 | * Constructs the filter with a custom name.
32 | */
33 | public Filter(String filterName) {
34 | mName = filterName;
35 | }
36 |
37 | /**
38 | * This abstract hook method must be overridden by a subclass to
39 | * define the logic for processing the given @a imageEntity.
40 | */
41 | protected abstract ImageEntity applyFilter(ImageEntity imageEntity);
42 |
43 | /**
44 | * This template method calls the applyFilter() hook method (which
45 | * must be defined by a subclass) to filter the @a imageEntity
46 | * parameter and sets the filterName of the result to the name of
47 | * the filter.
48 | */
49 | public ImageEntity filter(ImageEntity imageEntity) {
50 | // Call the applyFilter() hook method.
51 | ImageEntity filteredResult = applyFilter(imageEntity);
52 | filteredResult.setFilterName(this);
53 | return filteredResult;
54 | }
55 |
56 | /**
57 | * Sets the name of the filter.
58 | */
59 | public void setName(String filterName) {
60 | mName = filterName;
61 | }
62 |
63 | /**
64 | * Gets the name of the filter.
65 | */
66 | public String getName() {
67 | return mName;
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/ex/ImageTaskGang/src/example/imagetaskgang/filters/FilterDecorator.java:
--------------------------------------------------------------------------------
1 | package example.imagetaskgang.filters;
2 |
3 | import example.imagetaskgang.ImageEntity;
4 |
5 | /**
6 | * @class FilterDecorator
7 | *
8 | * @brief Allows the addition of behavior to a Filter object
9 | * transparently without affecting the behavior of other Filter
10 | * objects it encapsulates. Plays the role of the "Decorator"
11 | * in the Decorator pattern and the role of the "Abstract
12 | * Class" in the Template Method pattern.
13 | */
14 | public abstract class FilterDecorator extends Filter {
15 | /**
16 | * The Filter that's being decorated.
17 | */
18 | protected Filter mFilter;
19 |
20 | /**
21 | * Constructor initializes superclass and data member with the
22 | * given @a filter.
23 | */
24 | public FilterDecorator(Filter filter) {
25 | super(filter.getName());
26 | mFilter = filter;
27 | }
28 |
29 | /**
30 | * An abstract hook method that "decorates" the Filter data member
31 | * by being applied to the imageEntity after it's been filtered.
32 | */
33 | protected abstract ImageEntity decorate(ImageEntity imageEntity);
34 |
35 | /**
36 | * This hook method is also a template method that forwards to the
37 | * decorated filter to filter the @a imageEntity parameter.
38 | */
39 | @Override
40 | protected ImageEntity applyFilter(ImageEntity imageEntity) {
41 | return decorate(mFilter.filter(imageEntity));
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/ex/ImageTaskGang/src/example/imagetaskgang/filters/GrayScaleFilter.java:
--------------------------------------------------------------------------------
1 | package example.imagetaskgang.filters;
2 |
3 | import example.imagetaskgang.ImageEntity;
4 | import example.imagetaskgang.PlatformStrategy;
5 |
6 | /**
7 | * @class Filter
8 | *
9 | * @brief A Filter sublcass that converts a downloaded image to
10 | * grayscale.
11 | */
12 | public class GrayScaleFilter extends Filter {
13 | /**
14 | * Constructs a default GrayScaleFilter.
15 | */
16 | public GrayScaleFilter() {}
17 |
18 | /**
19 | * Constructs a Grayscale filter with the given name. This
20 | * constructor can be used to specify the output directory the
21 | * grayscale filtered images should be stored in. This naming
22 | * functionality would also be useful for filters to which
23 | * parameters are passed. For example, a 5x5 box filter and a 3x3
24 | * box filter could reuse identical code, but be stored in
25 | * different directories after processing.
26 | */
27 | public GrayScaleFilter(String name) {
28 | super(name);
29 | }
30 |
31 | /**
32 | * Uses the common color transformation values for grayscale
33 | * conversion using a pixel-by-pixel coloring algorithm.
34 | */
35 | @Override
36 | protected ImageEntity applyFilter(ImageEntity imageEntity) {
37 | // Forward to the platform-specific implementation of this
38 | // filter.
39 | return PlatformStrategy.instance().grayScaleFilter(imageEntity);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/ex/ImageTaskGang/src/example/imagetaskgang/filters/NullFilter.java:
--------------------------------------------------------------------------------
1 | package example.imagetaskgang.filters;
2 |
3 | import example.imagetaskgang.ImageEntity;
4 |
5 | /**
6 | * @class NullFilter
7 | *
8 | * @brief The NullFilter will return the image as it was downloaded.
9 | * It's purpose is to show the original image, as well as to
10 | * exemplify how filters are supposed to work on a basic level.
11 | * It plays the role of the "Concrete Component" in the
12 | * Decorator pattern and the "Concrete Class" in the Template
13 | * Method pattern.
14 | */
15 | public class NullFilter extends Filter {
16 | /**
17 | * Default constructor is a no-op.
18 | */
19 | public NullFilter() {}
20 |
21 | /**
22 | * Constructors for the NullFilter. See GrayScaleFilter for
23 | * explanation of filter naming.
24 | */
25 | public NullFilter(String name) {
26 | super(name);
27 | }
28 |
29 | /**
30 | * Constructs a new ImageEntity that does not change the original
31 | * at all.
32 | */
33 | @Override
34 | protected ImageEntity applyFilter(ImageEntity imageEntity) {
35 | return imageEntity;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/ex/ImageTaskGang/src/example/imagetaskgang/filters/OutputFilterDecorator.java:
--------------------------------------------------------------------------------
1 | package example.imagetaskgang.filters;
2 |
3 | import example.imagetaskgang.ImageEntity;
4 | import example.imagetaskgang.PlatformStrategy;
5 |
6 | /**
7 | * @class OutputFilterDecorator
8 | *
9 | * @brief A Decorator whose inherited applyFilter() template method
10 | * calls the filter() method on the Filter object passed to its
11 | * constructor and whose decorate() hook method then writes the
12 | * results of the filtered image to an output file. Plays the
13 | * role of the "Concrete Decorator" in the Decorator pattern
14 | * and the role of the "Concrete Class" in the Template Method
15 | * pattern.
16 | */
17 | public class OutputFilterDecorator extends FilterDecorator {
18 | /**
19 | * Constructor passes the @a filter parameter up to the superclass
20 | * constructor, which stores it in a data member for subsequent
21 | * use in applyFilter(), which is both a hook method and a
22 | * template method.
23 | */
24 | public OutputFilterDecorator(Filter filter) {
25 | super(filter);
26 | }
27 |
28 | /**
29 | * This hook method is called with the @a imageEntity parameter
30 | * after it has been filtered with mFilter in the inherited
31 | * applyFilter() method. decorate() stores the filtered
32 | * ImageEntity in a file.
33 | */
34 | @Override
35 | protected ImageEntity decorate(ImageEntity imageEntity) {
36 | // Store the filtered image as its filename (which is derived
37 | // from its URL), within the appropriate filter directory to
38 | // organize the filtered results and write the image to
39 | // the file in the appropriate directory.
40 | PlatformStrategy.instance()
41 | .storeExternalImage(this.getName(),
42 | imageEntity.getFileName(),
43 | imageEntity.getImage());
44 |
45 | return imageEntity;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/ex/ImageTaskGang/src/example/imagetaskgang/servermodel/FilterData.java:
--------------------------------------------------------------------------------
1 | package example.imagetaskgang.servermodel;
2 |
3 | import java.util.List;
4 |
5 | public class FilterData {
6 |
7 | public String filterName;
8 | public List imageData;
9 |
10 | public FilterData(String name, List data) {
11 | this.filterName = name;
12 | this.imageData = data;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/ex/ImageTaskGang/src/example/imagetaskgang/servermodel/ImageData.java:
--------------------------------------------------------------------------------
1 | package example.imagetaskgang.servermodel;
2 |
3 | public class ImageData {
4 |
5 | public String imageName;
6 | public String image;
7 |
8 | public ImageData(String imgName, String img) {
9 | this.imageName = imgName;
10 | this.image = img;
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/ex/ImageTaskGang/src/example/imagetaskgang/servermodel/ImageStreamService.java:
--------------------------------------------------------------------------------
1 | package example.imagetaskgang.servermodel;
2 |
3 | import java.net.URL;
4 | import java.util.List;
5 |
6 | import retrofit.http.Body;
7 | import retrofit.http.POST;
8 |
9 | public interface ImageStreamService {
10 | @POST("/ImageStreamServlet")
11 | ServerResponse execute(@Body List> inputURLs);
12 | }
13 |
--------------------------------------------------------------------------------
/ex/ImageTaskGang/src/example/imagetaskgang/servermodel/ServerResponse.java:
--------------------------------------------------------------------------------
1 | package example.imagetaskgang.servermodel;
2 |
3 | import java.util.List;
4 |
5 | public class ServerResponse {
6 |
7 | public List filterList;
8 |
9 | public ServerResponse(List fList) {
10 | this.filterList = fList;
11 | }
12 | }
--------------------------------------------------------------------------------
/ex/ImageTaskGangConsole/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/ex/ImageTaskGangConsole/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | ImageTaskGang
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 |
15 | org.eclipse.jdt.core.javanature
16 |
17 |
18 |
--------------------------------------------------------------------------------
/ex/ImageTaskGangConsole/DownloadImages/GrayScaleFilter/douglass.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/ImageTaskGangConsole/DownloadImages/GrayScaleFilter/douglass.jpg
--------------------------------------------------------------------------------
/ex/ImageTaskGangConsole/DownloadImages/GrayScaleFilter/ironbound.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/ImageTaskGangConsole/DownloadImages/GrayScaleFilter/ironbound.jpg
--------------------------------------------------------------------------------
/ex/ImageTaskGangConsole/DownloadImages/GrayScaleFilter/ka.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/ImageTaskGangConsole/DownloadImages/GrayScaleFilter/ka.png
--------------------------------------------------------------------------------
/ex/ImageTaskGangConsole/DownloadImages/GrayScaleFilter/lil-doug.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/ImageTaskGangConsole/DownloadImages/GrayScaleFilter/lil-doug.jpg
--------------------------------------------------------------------------------
/ex/ImageTaskGangConsole/DownloadImages/GrayScaleFilter/uci.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/ImageTaskGangConsole/DownloadImages/GrayScaleFilter/uci.png
--------------------------------------------------------------------------------
/ex/ImageTaskGangConsole/DownloadImages/GrayScaleFilter/wm.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/ImageTaskGangConsole/DownloadImages/GrayScaleFilter/wm.jpg
--------------------------------------------------------------------------------
/ex/ImageTaskGangConsole/DownloadImages/NullFilter/douglass.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/ImageTaskGangConsole/DownloadImages/NullFilter/douglass.jpg
--------------------------------------------------------------------------------
/ex/ImageTaskGangConsole/DownloadImages/NullFilter/ironbound.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/ImageTaskGangConsole/DownloadImages/NullFilter/ironbound.jpg
--------------------------------------------------------------------------------
/ex/ImageTaskGangConsole/DownloadImages/NullFilter/ka.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/ImageTaskGangConsole/DownloadImages/NullFilter/ka.png
--------------------------------------------------------------------------------
/ex/ImageTaskGangConsole/DownloadImages/NullFilter/lil-doug.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/ImageTaskGangConsole/DownloadImages/NullFilter/lil-doug.jpg
--------------------------------------------------------------------------------
/ex/ImageTaskGangConsole/DownloadImages/NullFilter/uci.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/ImageTaskGangConsole/DownloadImages/NullFilter/uci.png
--------------------------------------------------------------------------------
/ex/ImageTaskGangConsole/DownloadImages/NullFilter/wm.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/ImageTaskGangConsole/DownloadImages/NullFilter/wm.jpg
--------------------------------------------------------------------------------
/ex/ImageTaskGangConsole/src/example/imagetaskgang/BufferedImage.java:
--------------------------------------------------------------------------------
1 | package example.imagetaskgang;
2 |
3 | import java.io.ByteArrayInputStream;
4 | import java.io.IOException;
5 |
6 | import javax.imageio.ImageIO;
7 |
8 | /**
9 | * @class BufferedImage
10 | *
11 | * @brief Encapsulates the Java BufferedImage class via a
12 | * platform-independent interface.
13 | */
14 | class BufferedImage implements Image {
15 | /**
16 | * A Java BufferedImage object.
17 | */
18 | public java.awt.image.BufferedImage mBufferedImage;
19 |
20 | /**
21 | * Constructor that converts an @a imageData of raw bytes into a
22 | * Java @a BufferedImage.
23 | */
24 | public BufferedImage(byte[] imageData) {
25 | try {
26 | mBufferedImage = ImageIO.read(new ByteArrayInputStream(imageData));
27 | } catch (IOException e) {
28 | e.printStackTrace();
29 | }
30 | }
31 |
32 | /**
33 | * Constructor that stores the @a bufferedInmage parameter into
34 | * the data member.
35 | */
36 | public BufferedImage (Object bufferedImage) {
37 | mBufferedImage = (java.awt.image.BufferedImage) bufferedImage;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/ex/ImageTaskGangConsole/src/example/imagetaskgang/Filter.java:
--------------------------------------------------------------------------------
1 | package example.imagetaskgang;
2 |
3 | /**
4 | * @class Filter
5 | *
6 | * @brief An abstract class that defines a means to apply filtering
7 | * operations to an Image. It has a name and an abstract Filter
8 | * method whose implementation must be overridden by a
9 | * subclass. Plays the role of the "Abstract Class" in the
10 | * Template Method pattern and the role of the "Component" in
11 | * the Decorator pattern.
12 | */
13 | public abstract class Filter {
14 | /**
15 | * The name of the filter. Defaults to the Canonical Name of the
16 | * derived filter.
17 | */
18 | protected String mName;
19 |
20 | /**
21 | * Constructs the filter with the default name.
22 | */
23 | public Filter() {
24 | String baseName = this.getClass().getCanonicalName();
25 | mName = baseName.substring(baseName.lastIndexOf(".") + 1);
26 | }
27 |
28 | /**
29 | * Constructs the filter with a custom name.
30 | */
31 | public Filter(String name) {
32 | mName = name;
33 | }
34 |
35 | /**
36 | * Sets the name of the filter.
37 | */
38 | public void setName(String name) {
39 | mName = name;
40 | }
41 |
42 | /**
43 | * Gets the name of the filter.
44 | */
45 | public String getName() {
46 | return mName;
47 | }
48 |
49 | /**
50 | * This template method calls the applyFilter() hook method (which
51 | * must be defined by a subclass) to filter the @a imageEntity
52 | * parameter and sets the filterName of the result to the name of
53 | * the filter.
54 | */
55 | public ImageEntity filter(ImageEntity imageEntity) {
56 | // Call the applyFilter() hook method.
57 | ImageEntity filteredResult = applyFilter(imageEntity);
58 | filteredResult.setFilterName(this);
59 | return filteredResult;
60 | }
61 |
62 | /**
63 | * This abstract hook method must be overridden by a subclass to
64 | * define the logic for processing the given @a imageEntity.
65 | */
66 | protected abstract ImageEntity applyFilter(ImageEntity imageEntity);
67 | }
68 |
--------------------------------------------------------------------------------
/ex/ImageTaskGangConsole/src/example/imagetaskgang/FilterDecorator.java:
--------------------------------------------------------------------------------
1 | package example.imagetaskgang;
2 |
3 | /**
4 | * @class FilterDecorator
5 | *
6 | * @brief Allows the addition of behavior to an object dynamically
7 | * without affecting the behavior of other objects from the
8 | * same class. Plays the role of the "Decorator" in the
9 | * Decorator pattern.
10 | */
11 | public abstract class FilterDecorator extends Filter {
12 | /**
13 | * The Filter that's being decorated.
14 | */
15 | protected Filter mFilter;
16 |
17 | /**
18 | * Constructor initializes superclass and data member with the
19 | * given @a filter.
20 | */
21 | public FilterDecorator(Filter filter) {
22 | super(filter.getName());
23 | mFilter = filter;
24 | }
25 |
26 | /**
27 | * This hook method forwards to the decorated filter to filter the
28 | * @a imageEntity parameter.
29 | */
30 | @Override
31 | protected ImageEntity applyFilter(ImageEntity imageEntity) {
32 | return decorate(mFilter.filter(imageEntity));
33 | }
34 |
35 | /**
36 | * An abstract hook method that "decorates" the data member
37 | * filter, which is applied to the imageEntity after it's been
38 | * filtered.
39 | */
40 | protected abstract ImageEntity decorate(ImageEntity imageEntity);
41 | }
42 |
--------------------------------------------------------------------------------
/ex/ImageTaskGangConsole/src/example/imagetaskgang/GrayScaleFilter.java:
--------------------------------------------------------------------------------
1 | package example.imagetaskgang;
2 |
3 | /**
4 | * @class Filter
5 | *
6 | * @brief A Filter sublcass that converts a downloaded image to
7 | * grayscale.
8 | */
9 | public class GrayScaleFilter extends Filter {
10 | /**
11 | * Constructs a default GrayScaleFilter.
12 | */
13 | public GrayScaleFilter() {}
14 |
15 | /**
16 | * Constructs a Grayscale filter with the given name. This
17 | * constructor can be used to specify the output directory the
18 | * grayscale filtered images should be stored in. This naming
19 | * functionality would also be useful for filters to which
20 | * parameters are passed. For example, a 5x5 box filter and a 3x3
21 | * box filter could reuse identical code, but be stored in
22 | * different directories after processing.
23 | */
24 | public GrayScaleFilter(String name) {
25 | super(name);
26 | }
27 |
28 | /**
29 | * Uses the common color transformation values for grayscale
30 | * conversion using a pixel-by-pixel coloring algorithm.
31 | */
32 | @Override
33 | protected ImageEntity applyFilter(ImageEntity imageEntity) {
34 | // Forward to the platform-specific implementation of this
35 | // filter.
36 | return PlatformStrategy.instance().grayScaleFilter(imageEntity);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/ex/ImageTaskGangConsole/src/example/imagetaskgang/Image.java:
--------------------------------------------------------------------------------
1 | package example.imagetaskgang;
2 |
3 | /**
4 | * @class Image
5 | *
6 | * @brief Defines a platform-independent Image interface, which can be
7 | * implemented for different runtime environments, e.g.,
8 | * Android or plain Java.
9 | */
10 | interface Image {
11 | }
12 |
--------------------------------------------------------------------------------
/ex/ImageTaskGangConsole/src/example/imagetaskgang/NullFilter.java:
--------------------------------------------------------------------------------
1 | package example.imagetaskgang;
2 |
3 | /**
4 | * @class NullFilter
5 | *
6 | * @brief The NullFilter will return the image as it was downloaded.
7 | * It's main purpose is to show the "Control" image, and to
8 | * exemplify how filters are supposed to work on a basic level.
9 | */
10 | public class NullFilter extends Filter {
11 | /**
12 | * Default constructor is a no-op.
13 | */
14 | public NullFilter() {}
15 |
16 | /**
17 | * Constructors for the NullFilter. See GrayScaleFilter for
18 | * explanation of filter naming.
19 | */
20 | public NullFilter(String name) {
21 | super(name);
22 | }
23 |
24 | /**
25 | * Constructs a new ImageEntity that does not change the original
26 | * at all.
27 | */
28 | @Override
29 | protected ImageEntity applyFilter(ImageEntity imageEntity) {
30 | return imageEntity;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/ex/ImageTaskGangConsole/src/example/imagetaskgang/OutputFilterDecorator.java:
--------------------------------------------------------------------------------
1 | package example.imagetaskgang;
2 |
3 | import java.io.File;
4 | import java.io.FileOutputStream;
5 |
6 | /**
7 | * @class OutputFilterDecorator
8 | *
9 | * @brief A Decorator that applies the filter passed to its
10 | * constructor and then writes the results to an output file.
11 | * Plays the role of the "Concrete Decorator" in the Decorator
12 | * pattern.
13 | */
14 | public class OutputFilterDecorator extends FilterDecorator {
15 | /**
16 | * Constructs the filter decorator with the @a filter to apply.
17 | */
18 | public OutputFilterDecorator(Filter filter) {
19 | super(filter);
20 | }
21 |
22 | /**
23 | * The hook method that is called on the ImageEntity once it has
24 | * been filtered with mFilter. This method stores the filtered
25 | * ImageEntity in a file by delegating the storing to the
26 | * platform- specific implementation of storeImage(...).
27 | */
28 | @Override
29 | protected ImageEntity decorate(ImageEntity imageEntity) {
30 | if (true) {
31 | // Call the applyFilter() hook method.
32 | ImageEntity result = (ImageEntity) imageEntity;
33 |
34 | // Make a directory for the filter if it does not already
35 | // exist.
36 | File externalFile =
37 | new File(PlatformStrategy.instance().getDirectoryPath(),
38 | this.getName());
39 | externalFile.mkdirs();
40 |
41 | // We will store the filtered image as its original filename,
42 | // within the appropriate filter directory to organize the
43 | // filtered results.
44 | File newImage =
45 | new File(externalFile,
46 | result.getFileName());
47 |
48 | // Write the compressed image to the appropriate directory.
49 | try (FileOutputStream outputFile = new FileOutputStream(newImage)) {
50 | PlatformStrategy.instance().storeImage(result.getImage(),
51 | outputFile);
52 | } catch (Exception e) {
53 | // Try-with-resources will clean up resources.
54 | e.printStackTrace();
55 | return null;
56 | }
57 |
58 | return result;
59 | } else {
60 | PlatformStrategy.instance().errorLog
61 | ("OutoutFileDecorator",
62 | "sdcard isn't mounted");
63 | return null;
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/ex/PingPongWrong/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/ex/PingPongWrong/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | PingPongWrong
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 |
15 | org.eclipse.jdt.core.javanature
16 |
17 |
18 |
--------------------------------------------------------------------------------
/ex/PingPongWrong/src/PingPongWrong.java:
--------------------------------------------------------------------------------
1 | import java.util.concurrent.Semaphore;
2 | import java.util.concurrent.CountDownLatch;
3 |
4 | /**
5 | * @class PingPongWrong
6 | *
7 | * @brief This class implements a Java program that creates two
8 | * threads that attempt to alternately print "Ping" and "Pong",
9 | * respectively, on the display. This implementation behaves
10 | * incorrectly due to lack of synchronization between the
11 | * threads. It's also hard-coded to run as a Java console
12 | * application and thus can't work in Android without major
13 | * changes.
14 | */
15 | public class PingPongWrong
16 | {
17 | /**
18 | * Number of iterations to play ping/pong.
19 | */
20 | public static int mMaxIterations = 10;
21 |
22 | /**
23 | * @brief PlayPingPongThread
24 | *
25 | * @class This class implements the incorrect non-synchronized
26 | * version of the ping/pong application.
27 | */
28 | public static class PlayPingPongThread extends Thread
29 | {
30 | public PlayPingPongThread (String stringToPrint)
31 | {
32 | this.mStringToPrint = stringToPrint;
33 | }
34 |
35 | /**
36 | * Main event loop that runs in a separate thread of control.
37 | */
38 | public void run ()
39 | {
40 | for (int loopsDone = 1;
41 | loopsDone <= mMaxIterations;
42 | ++loopsDone)
43 | // Print out the iteration.
44 | System.out.println(mStringToPrint + "(" + loopsDone + ")");
45 |
46 | // Exit the thread when the loop is done.
47 | }
48 |
49 | // The string to print for each ping and pong operation.
50 | private String mStringToPrint;
51 | }
52 |
53 | public static void main(String[] args) {
54 | try {
55 | System.out.println("Ready...Set...Go!");
56 |
57 | // Create the ping and pong threads.
58 | PlayPingPongThread ping =
59 | new PlayPingPongThread("Ping!");
60 | PlayPingPongThread pong =
61 | new PlayPingPongThread("Pong!");
62 |
63 | // Start ping and pong threads, which calls their run()
64 | // methods.
65 | ping.start();
66 | pong.start();
67 |
68 | // Wait for both threads to exit before exiting main().
69 | ping.join();
70 | pong.join();
71 |
72 | System.out.println("Done!");
73 | }
74 | catch (java.lang.InterruptedException e)
75 | {}
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/ex/SearchTaskGang/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/ex/SearchTaskGang/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | SearchTaskGang
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 |
15 | org.eclipse.jdt.core.javanature
16 |
17 |
18 |
--------------------------------------------------------------------------------
/ex/SimpleBlockingQueue/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/ex/SimpleBlockingQueue/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | SimpleBlockingQueue
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 |
15 | org.eclipse.jdt.core.javanature
16 |
17 |
18 |
--------------------------------------------------------------------------------
/ex/TaskGang/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/ex/TaskGang/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | TaskGang
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 |
15 | org.eclipse.jdt.core.javanature
16 |
17 |
18 |
--------------------------------------------------------------------------------
/ex/TaskGang/src/CyclicExecutorService.java:
--------------------------------------------------------------------------------
1 | import java.util.ArrayList;
2 | import java.util.List;
3 | import java.util.concurrent.Callable;
4 | import java.util.concurrent.ExecutorService;
5 | import java.util.concurrent.Executors;
6 |
7 | /**
8 | * @class CyclicExecutorService
9 | *
10 | * @brief Customizes the SearchTaskGangCommon framework to process
11 | * a cyclic List of tasks via a pool of Threads created by
12 | * the Executor, which is also used to wait for all
13 | * the Threads in the pool to shutdown.
14 | */
15 | public class CyclicExecutorService
16 | extends OneShotExecutorService {
17 | /**
18 | * Constructor initializes the superclass.
19 | */
20 | CyclicExecutorService(String[] wordsToFind,
21 | String[][] stringsToSearch) {
22 | // Pass input to superclass constructor.
23 | super(wordsToFind,
24 | stringsToSearch);
25 | }
26 |
27 | /**
28 | * Initiate the TaskGang to run each worker in the Thread
29 | * pool.
30 | */
31 | protected void initiateTaskGang(int inputSize) {
32 | // Allow subclasses to customize their behavior before the
33 | // Threads in the gang are spawned.
34 | initiateHook(inputSize);
35 |
36 | // Create a new collection that will contain all the
37 | // Worker Runnables.
38 | List> workerCollection =
39 | new ArrayList>(inputSize);
40 |
41 | // Create a Runnable for each item in the input List and
42 | // add it as a Callable adapter into the collection.
43 | for (int i = 0; i < inputSize; ++i)
44 | workerCollection.add(Executors.callable(makeTask(i)));
45 |
46 | try {
47 | ExecutorService executorService =
48 | (ExecutorService) getExecutor();
49 |
50 | // Use invokeAll() to execute all items in the collection
51 | // via the Executor's Thread pool.
52 | executorService.invokeAll(workerCollection);
53 | } catch (InterruptedException e) {
54 | System.out.println("invokeAll() interrupted");
55 | }
56 | }
57 |
58 | /**
59 | * When there's no more input data to process release the exit
60 | * latch and return false so the worker Thread will return.
61 | * Otherwise, return true so the worker Thread will continue
62 | * to run.
63 | */
64 | @Override
65 | protected boolean advanceTaskToNextCycle() {
66 | if (setInput(getNextInput()) == null)
67 | return false;
68 | else {
69 | // Invoke method to initialize the gang of Threads.
70 | initiateTaskGang(getInput().size());
71 |
72 | return true;
73 | }
74 | }
75 | }
76 |
77 |
--------------------------------------------------------------------------------
/ex/ThreadGang/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/ex/ThreadGang/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | ThreadGang
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 |
15 | org.eclipse.jdt.core.javanature
16 |
17 |
18 |
--------------------------------------------------------------------------------
/ex/ThreadedDownloads/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/ex/ThreadedDownloads/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | ThreadedDownloads
4 |
5 |
6 |
7 |
8 |
9 | com.android.ide.eclipse.adt.ResourceManagerBuilder
10 |
11 |
12 |
13 |
14 | com.android.ide.eclipse.adt.PreCompilerBuilder
15 |
16 |
17 |
18 |
19 | org.eclipse.jdt.core.javabuilder
20 |
21 |
22 |
23 |
24 | com.android.ide.eclipse.adt.ApkBuilder
25 |
26 |
27 |
28 |
29 |
30 | com.android.ide.eclipse.adt.AndroidNature
31 | org.eclipse.jdt.core.javanature
32 |
33 |
34 |
--------------------------------------------------------------------------------
/ex/ThreadedDownloads/.settings/org.eclipse.jdt.core.prefs:
--------------------------------------------------------------------------------
1 | eclipse.preferences.version=1
2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
4 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
5 | org.eclipse.jdt.core.compiler.compliance=1.7
6 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate
7 | org.eclipse.jdt.core.compiler.debug.localVariable=generate
8 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate
9 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
10 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
11 | org.eclipse.jdt.core.compiler.source=1.7
12 |
--------------------------------------------------------------------------------
/ex/ThreadedDownloads/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
11 |
12 |
17 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/ex/ThreadedDownloads/gen/edu/vuum/mocca/BuildConfig.java:
--------------------------------------------------------------------------------
1 | /** Automatically generated file. DO NOT MODIFY */
2 | package edu.vuum.mocca;
3 |
4 | public final class BuildConfig {
5 | public final static boolean DEBUG = true;
6 | }
--------------------------------------------------------------------------------
/ex/ThreadedDownloads/gen/edu/vuum/mocca/R.java:
--------------------------------------------------------------------------------
1 | /* AUTO-GENERATED FILE. DO NOT MODIFY.
2 | *
3 | * This class was automatically generated by the
4 | * aapt tool from the resource data it found. It
5 | * should not be modified by hand.
6 | */
7 |
8 | package edu.vuum.mocca;
9 |
10 | public final class R {
11 | public static final class attr {
12 | }
13 | public static final class drawable {
14 | public static final int default_image=0x7f020000;
15 | public static final int ic_action_search=0x7f020001;
16 | public static final int ic_icon=0x7f020002;
17 | public static final int ic_launcher=0x7f020003;
18 | }
19 | public static final class id {
20 | public static final int about=0x7f070007;
21 | public static final int async_task_button=0x7f070003;
22 | public static final int help=0x7f070006;
23 | public static final int mImageView=0x7f070005;
24 | public static final int mUrlEditText=0x7f070000;
25 | public static final int messages_button=0x7f070002;
26 | public static final int reset_image_button=0x7f070004;
27 | public static final int runnable_button=0x7f070001;
28 | }
29 | public static final class layout {
30 | public static final int main=0x7f030000;
31 | }
32 | public static final class menu {
33 | public static final int options=0x7f060000;
34 | }
35 | public static final class string {
36 | public static final int about=0x7f04000a;
37 | public static final int app_name=0x7f040000;
38 | public static final int defaultURL=0x7f040007;
39 | public static final int help=0x7f040009;
40 | public static final int location=0x7f040008;
41 | public static final int menu_settings=0x7f040001;
42 | public static final int resetImage=0x7f040006;
43 | public static final int runAsyncTask=0x7f040005;
44 | public static final int runMessages=0x7f040004;
45 | public static final int runRunnable=0x7f040003;
46 | public static final int title_activity_threadeddownloads=0x7f040002;
47 | }
48 | public static final class style {
49 | public static final int AppTheme=0x7f050000;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/ex/ThreadedDownloads/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system edit
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 | #
10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
12 |
13 | # Project target.
14 | target=android-19
15 |
16 |
--------------------------------------------------------------------------------
/ex/ThreadedDownloads/res/drawable-hdpi/default_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/ThreadedDownloads/res/drawable-hdpi/default_image.png
--------------------------------------------------------------------------------
/ex/ThreadedDownloads/res/drawable-hdpi/ic_action_search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/ThreadedDownloads/res/drawable-hdpi/ic_action_search.png
--------------------------------------------------------------------------------
/ex/ThreadedDownloads/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/ThreadedDownloads/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ex/ThreadedDownloads/res/drawable-ldpi/ic_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/ThreadedDownloads/res/drawable-ldpi/ic_icon.png
--------------------------------------------------------------------------------
/ex/ThreadedDownloads/res/drawable-ldpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/ThreadedDownloads/res/drawable-ldpi/ic_launcher.png
--------------------------------------------------------------------------------
/ex/ThreadedDownloads/res/drawable-mdpi/default_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/ThreadedDownloads/res/drawable-mdpi/default_image.png
--------------------------------------------------------------------------------
/ex/ThreadedDownloads/res/drawable-mdpi/ic_action_search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/ThreadedDownloads/res/drawable-mdpi/ic_action_search.png
--------------------------------------------------------------------------------
/ex/ThreadedDownloads/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/ThreadedDownloads/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ex/ThreadedDownloads/res/drawable-xhdpi/default_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/ThreadedDownloads/res/drawable-xhdpi/default_image.png
--------------------------------------------------------------------------------
/ex/ThreadedDownloads/res/drawable-xhdpi/ic_action_search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/ThreadedDownloads/res/drawable-xhdpi/ic_action_search.png
--------------------------------------------------------------------------------
/ex/ThreadedDownloads/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/ThreadedDownloads/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ex/ThreadedDownloads/res/layout/main.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
11 |
12 |
17 |
18 |
25 |
26 |
27 |
32 |
33 |
41 |
42 |
50 |
51 |
59 |
60 |
68 |
69 |
70 |
71 |
76 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/ex/ThreadedDownloads/res/menu/options.xml:
--------------------------------------------------------------------------------
1 |
11 |
--------------------------------------------------------------------------------
/ex/ThreadedDownloads/res/values-v11/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/ex/ThreadedDownloads/res/values-v14/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/ex/ThreadedDownloads/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | ThreadedDownload
4 | Settings
5 | ThreadedDownload
6 | Run\nRunnable
7 | Run\nMessages
8 | Run\nAsync
9 | Reset\nImage
10 | http://www.dre.vanderbilt.edu/~schmidt/ka.png
11 | Enter URL:
12 | Help
13 | About
14 |
15 |
16 |
--------------------------------------------------------------------------------
/ex/ThreadedDownloads/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
--------------------------------------------------------------------------------
/ex/ThreadedDownloads/src/edu/vuum/mocca/ButtonStrategy.java:
--------------------------------------------------------------------------------
1 | package edu.vuum.mocca;
2 |
3 | /**
4 | * @class ButtonStrategy
5 | *
6 | * @brief Implement this interface to define the concurrency strategy
7 | * used to download and display an image when the user clicks a
8 | * button. This interface plays the role of the "Strategy" in
9 | * the Strategy pattern.
10 | */
11 | public interface ButtonStrategy {
12 | /**
13 | * Define a strategy for downloading and displaying an image,
14 | * which is guided by the DownloadContext.
15 | */
16 | void downloadAndDisplayImage(DownloadContext downloadContext);
17 |
18 | /**
19 | * Define a strategy for canceling a download.
20 | */
21 | void cancelDownload(DownloadContext downloadContext);
22 | }
23 |
--------------------------------------------------------------------------------
/ex/ThreadedDownloads/src/edu/vuum/mocca/ButtonStrategyMapper.java:
--------------------------------------------------------------------------------
1 | package edu.vuum.mocca;
2 |
3 | import android.util.SparseArray;
4 |
5 | /**
6 | * @class ButtonStrategyMapper
7 | *
8 | * @brief Maps buttons (represented via their resource ids) to
9 | * ButtonStrategy implementations.
10 | */
11 | public class ButtonStrategyMapper {
12 | /**
13 | * Data structure that maps button Ids to ButtonStrategy objects.
14 | */
15 | private SparseArray mButtonStrategyArray =
16 | new SparseArray<>();
17 |
18 | /**
19 | * Constructor that uses SparseArray maps button Ids to
20 | * ButtonStrategy objects.
21 | */
22 | public ButtonStrategyMapper(int[] buttonIds,
23 | ButtonStrategy[] buttonStrategys) {
24 | // Map buttons pushed by the user to the requested type of
25 | // ButtonStrategy.
26 | for (int i = 0; i < buttonIds.length; ++i)
27 | mButtonStrategyArray.put(buttonIds[i],
28 | buttonStrategys[i]);
29 | }
30 |
31 | /**
32 | * Factory method that returns the request ButtonStrategy
33 | * implementation given a button Id.
34 | */
35 | public ButtonStrategy getButtonStrategy(int buttonId) {
36 | // Return the designated ButtonStrategy.
37 | return mButtonStrategyArray.get(buttonId);
38 | }
39 | }
40 |
41 |
--------------------------------------------------------------------------------
/ex/ThreadedDownloads/src/edu/vuum/mocca/DownloadWithRunnable.java:
--------------------------------------------------------------------------------
1 | package edu.vuum.mocca;
2 |
3 | import android.graphics.Bitmap;
4 |
5 | /**
6 | * @class DownloadWithRunnable
7 | *
8 | * @brief Use the Runnables and Handlers defined by the HaMeR
9 | * framework to implement the ConcurrencyStrategy interface and
10 | * download a bitmap image in a background Thread. This class
11 | * plays the role of the "Concrete Strategy" in the Strategy
12 | * pattern.
13 | */
14 | public class DownloadWithRunnable implements ButtonStrategy {
15 | /**
16 | * Thread object that's used for the download.
17 | */
18 | private Thread mThread = null;
19 |
20 | /**
21 | * Creates and starts a new Thread to download an image in the
22 | * background via a Runnable. The downloaded image is then
23 | * diplayed in the UI Thread by posting another Runnable via the
24 | * Activity's runOnUiThread() method, which uses an internal
25 | * Handler.
26 | */
27 | @Override
28 | public void downloadAndDisplayImage
29 | (final DownloadContext downloadContext) {
30 | final Runnable downloadRunnable = new Runnable() {
31 | /**
32 | * Download a bitmap image in a background Thread and then
33 | * post a Runnable to the UI Thread to set the image to
34 | * the ImageView.
35 | */
36 | @Override
37 | public void run() {
38 | // Download the image.
39 | final Bitmap image =
40 | downloadContext.downloadImage
41 | (downloadContext.getUrlString());
42 |
43 | // Display the downloaded image to the user.
44 | downloadContext.displayImage(image);
45 | }
46 | };
47 |
48 | // Inform the user that the download is starting with this
49 | // particular concurrency strategy.
50 | downloadContext.showToast
51 | ("downloading via Handlers and Runnables");
52 |
53 | // Create and Start a new Thread to perform the download and
54 | // display the results to the user.
55 | mThread = new Thread(downloadRunnable);
56 | mThread.start();
57 | }
58 |
59 | /**
60 | * Cancel the download.
61 | */
62 | @Override
63 | public void cancelDownload(DownloadContext downloadContext) {
64 | // Let the user know this download is being canceled.
65 | downloadContext.showToast
66 | ("Canceling DownloadWithRunnable in progress");
67 |
68 | // Interrupt the Thread so it will stop the download.
69 | mThread.interrupt();
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/ex/ThreadedDownloads/src/edu/vuum/mocca/ResetImage.java:
--------------------------------------------------------------------------------
1 | package edu.vuum.mocca;
2 |
3 | import edu.vuum.mocca.R;
4 |
5 | /**
6 | * @class ResetImage
7 | *
8 | * @brief This class resets the image displayed to the user with the
9 | * default image.
10 | */
11 | public class ResetImage implements ButtonStrategy {
12 | /**
13 | * Replace the current image with the default image.
14 | */
15 | public void downloadAndDisplayImage(DownloadContext downloadContext) {
16 | downloadContext.showToast("Resetting image to the default");
17 | downloadContext.resetImage(R.drawable.default_image);
18 | }
19 |
20 | /**
21 | * "Cancel" a download.
22 | */
23 | @Override
24 | public void cancelDownload(DownloadContext downloadContext) {
25 | // No-op.
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/ex/UserOrDaemonExecutor/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/ex/UserOrDaemonExecutor/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | UserOrDaemonExecutor
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 |
15 | org.eclipse.jdt.core.javanature
16 |
17 |
18 |
--------------------------------------------------------------------------------
/ex/UserOrDaemonRunnable/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/ex/UserOrDaemonRunnable/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | UserOrDaemonRunnable
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 |
15 | org.eclipse.jdt.core.javanature
16 |
17 |
18 |
--------------------------------------------------------------------------------
/ex/UserOrDaemonRunnable/src/TestRunnable.java:
--------------------------------------------------------------------------------
1 | /**
2 | * @class TestRunnable
3 | *
4 | * @brief This program demonstrates the difference between a Java user
5 | * thread and a daemon thread. If it's launched with no
6 | * command-line parameters the main thread creates a user
7 | * thread, which can outlive the main thread (i.e., it
8 | * continues to run even after the main thread exits). If it's
9 | * launched with a command-line parameter then it creates a
10 | * daemon thread, which exits when the main thread exits.
11 | */
12 | public class TestRunnable {
13 | /**
14 | * Entry point method into the program's main thread, which
15 | * creates/starts the desired type of thread (i.e., either "user"
16 | * or "daemon") and sleeps for 3 seconds while that thread runs.
17 | * If a "daemon" thread is created it will only run as long as the
18 | * main thread runs. Conversely, if a "user" thread is created it
19 | * will continue to run even after the main thread exits.
20 | */
21 | public static void main(String[] args) {
22 | System.out.println("Entering main()");
23 |
24 | // Create a "daemon" thread if any command-line parameter is
25 | // passed to the program.
26 | final Boolean daemonThread = args.length > 0;
27 |
28 | // Create the GCD Runnable, passing in the type of thread it
29 | // runs in (i.e., "user" or "daemon").
30 | GCDRunnable runnableCommand =
31 | new GCDRunnable(daemonThread ? "daemon" : "user");
32 |
33 | // Create a new Thread that's will execute the runnableCommand
34 | // concurrently.
35 | Thread thr = new Thread(runnableCommand);
36 |
37 | if (daemonThread)
38 | // Make the new Thread a "daemon".
39 | thr.setDaemon(true);
40 |
41 | // Start the thread.
42 | thr.start();
43 |
44 | // Sleep for 1 second and then exit.
45 | try {
46 | Thread.sleep(1000);
47 | } catch (InterruptedException x) {}
48 |
49 | System.out.println("Leaving main()");
50 | }
51 | }
52 |
53 |
--------------------------------------------------------------------------------
/ex/UserOrDaemonThread/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/ex/UserOrDaemonThread/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | UserOrDaemonThread
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 |
15 | org.eclipse.jdt.core.javanature
16 |
17 |
18 |
--------------------------------------------------------------------------------
/ex/UserOrDaemonThread/src/TestThread.java:
--------------------------------------------------------------------------------
1 | /**
2 | * @class TestThread
3 | *
4 | * @brief This program demonstrates the difference between a Java user
5 | * thread and a daemon thread. If it's launched with no
6 | * command-line parameters the main thread creates a user
7 | * thread, which can outlive the main thread (i.e., it
8 | * continues to run even after the main thread exits). If it's
9 | * launched with a command-line parameter then it creates a
10 | * daemon thread, which exits when the main thread exits.
11 | */
12 | public class TestThread {
13 | /**
14 | * Entry point method into the program's main thread, which
15 | * creates/starts the desired type of thread (i.e., either "user"
16 | * or "daemon") and sleeps for 3 seconds while that thread runs.
17 | * If a "daemon" thread is created it will only run as long as the
18 | * main thread runs. Conversely, if a "user" thread is created it
19 | * will continue to run even after the main thread exits.
20 | */
21 | public static void main(String[] args) {
22 | System.out.println("Entering main()");
23 |
24 | // Create a "daemon" thread if any command-line parameter is
25 | // passed to the program.
26 | final Boolean daemonThread = args.length > 0;
27 |
28 | // Create the appropriate type of thread (i.e., "user" or
29 | // "daemon").
30 | UserOrDaemonThread thr =
31 | new UserOrDaemonThread(daemonThread);
32 |
33 | // Start the thread.
34 | thr.start();
35 |
36 | // Sleep for 1 second and then exit.
37 | try {
38 | Thread.sleep(1000);
39 | } catch (InterruptedException x) {}
40 |
41 | System.out.println("Leaving main()");
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/ex/UserThreadInterrupted/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/ex/UserThreadInterrupted/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | UserThreadInterrupted
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 |
15 | org.eclipse.jdt.core.javanature
16 |
17 |
18 |
--------------------------------------------------------------------------------
/ex/UserThreadInterrupted/src/GCDRunnable.java:
--------------------------------------------------------------------------------
1 | import java.util.Random;
2 |
3 | /**
4 | * @class GCDRunnable
5 | *
6 | * @brief Computes the greatest common divisor (GCD) of two numbers.
7 | */
8 | public class GCDRunnable
9 | extends Random // Inherits random number generation capabilities.
10 | implements Runnable {
11 | /**
12 | * Number of times to iterate, which is 100 million to ensure the
13 | * program runs for a while.
14 | */
15 | private final int MAX_ITERATIONS = 100000000;
16 |
17 | /**
18 | * Provides a recursive implementation of Euclid's algorithm to
19 | * compute the "greatest common divisor" (GCD), which is the
20 | * largest positive integer that divides two integers without a
21 | * remainder.
22 | */
23 | private int computeGCD(int number1,
24 | int number2) {
25 | // Basis case.
26 | if (number2 == 0)
27 | return number1;
28 | // Recursive call.
29 | return computeGCD(number2,
30 | number1 % number2);
31 | }
32 |
33 | /**
34 | * Hook method that runs for MAX_ITERATIONs, sleeping for half a
35 | * second at a time.
36 | */
37 | public void run() {
38 | final String threadString =
39 | " with thread id "
40 | + Thread.currentThread();
41 |
42 | System.out.println("Entering run()"
43 | + threadString);
44 |
45 | try {
46 | for(int i = 0; i < MAX_ITERATIONS; ++i) {
47 | // Generate two random numbers.
48 | int number1 = nextInt();
49 | int number2 = nextInt();
50 |
51 | if(Thread.interrupted())
52 | throw new InterruptedException();
53 | // Print results every 10 million iterations.
54 | else if((i % 10000000) == 0)
55 | System.out.println("In run()"
56 | + threadString
57 | + " the GCD of "
58 | + number1
59 | + " and "
60 | + number2
61 | + " is "
62 | + computeGCD(number1,
63 | number2));
64 | }
65 | } catch (InterruptedException e) {
66 | System.out.println("Thread interrupted"
67 | + threadString);
68 | } finally {
69 | System.out.println("Leaving run() "
70 | + threadString);
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/ex/UserThreadInterrupted/src/RunnableFuture.java:
--------------------------------------------------------------------------------
1 | /*
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3 | *
4 | * This code is free software; you can redistribute it and/or modify it
5 | * under the terms of the GNU General Public License version 2 only, as
6 | * published by the Free Software Foundation. Oracle designates this
7 | * particular file as subject to the "Classpath" exception as provided
8 | * by Oracle in the LICENSE file that accompanied this code.
9 | *
10 | * This code is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 | * version 2 for more details (a copy is included in the LICENSE file that
14 | * accompanied this code).
15 | *
16 | * You should have received a copy of the GNU General Public License version
17 | * 2 along with this work; if not, write to the Free Software Foundation,
18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 | *
20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 | * or visit www.oracle.com if you need additional information or have any
22 | * questions.
23 | */
24 |
25 | /*
26 | * This file is available under and governed by the GNU General Public
27 | * License version 2 only, as published by the Free Software Foundation.
28 | * However, the following notice accompanied the original version of this
29 | * file:
30 | *
31 | * Written by Doug Lea with assistance from members of JCP JSR-166
32 | * Expert Group and released to the public domain, as explained at
33 | * http://creativecommons.org/publicdomain/zero/1.0/
34 | */
35 |
36 | package java.util.concurrent;
37 |
38 | /**
39 | * A {@link Future} that is {@link Runnable}. Successful execution of
40 | * the {@code run} method causes completion of the {@code Future}
41 | * and allows access to its results.
42 | * @see FutureTask
43 | * @see Executor
44 | * @since 1.6
45 | * @author Doug Lea
46 | * @param The result type returned by this Future's {@code get} method
47 | */
48 | public interface RunnableFuture extends Runnable, Future {
49 | /**
50 | * Sets this Future to the result of its computation
51 | * unless it has been cancelled.
52 | */
53 | void run();
54 | }
55 |
--------------------------------------------------------------------------------
/ex/UserThreadInterrupted/src/TestInterrupted.java:
--------------------------------------------------------------------------------
1 | /**
2 | * @class TestInterrupted
3 | *
4 | * @brief This program demonstrates how to interrupt a running user
5 | * Java thread that computes the greatest common divisor (GCD).
6 | * If there are no command-line arguments then sleep for 4
7 | * seconds while the thread computes the GCD in the background
8 | * and then send it an interrupt request to cause the thread to
9 | * exit. If it's launched with any command-line arguments the
10 | * thread computing the GCD can continue to run even after the
11 | * main thread exits.
12 | */
13 | public class TestInterrupted {
14 | /**
15 | * Entry point method into the program's main thread, which
16 | * creates/starts a user thread to compute the GCD and interrupt
17 | * it.
18 | */
19 | public static void main(String[] args) {
20 | System.out.println("Entering main()");
21 |
22 | // If there are no arguments then interrupt the thread,
23 | // otherwise, don't interrupt it.
24 | final Boolean interruptThread = args.length == 0;
25 |
26 | // Create the GCD Runnable, passing in the type of thread it
27 | // runs in (i.e., "user" or "daemon").
28 | GCDRunnable runnableCommand =
29 | new GCDRunnable();
30 |
31 | // Create a new Thread that's will execute the runnableCommand
32 | // concurrently.
33 | Thread thr = new Thread(runnableCommand);
34 |
35 | // Start the user thread.
36 | thr.start();
37 |
38 | try {
39 | if(interruptThread) {
40 | // Sleep for 4 seconds and then interrupt the Thread.
41 | Thread.sleep(4000);
42 |
43 | System.out.println("interrupting thread "
44 | + thr.getName());
45 |
46 | // Send the thread an interrupt request.
47 | thr.interrupt();
48 | }
49 |
50 | // Sleep for another second and then exit.
51 | Thread.sleep(1000);
52 | } catch (InterruptedException x) {}
53 |
54 | System.out.println("Leaving main()");
55 | }
56 | }
57 |
58 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/.gitignore:
--------------------------------------------------------------------------------
1 | # Built application files
2 | *.apk
3 | *.ap_
4 |
5 | # Files for the Dalvik VM
6 | *.dex
7 |
8 | # Java class files
9 | *.class
10 |
11 | # Generated files
12 | bin/
13 | gen/
14 |
15 | # Gradle files
16 | .gradle/
17 | build/
18 | /*/build/
19 |
20 | # Local configuration file (sdk path, etc)
21 | local.properties
22 |
23 | # Proguard folder generated by Eclipse
24 | proguard/
25 |
26 | # Log Files
27 | *.log
28 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Android/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Android/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | Weekendizer
4 |
5 |
6 |
7 |
8 |
9 | com.android.ide.eclipse.adt.ResourceManagerBuilder
10 |
11 |
12 |
13 |
14 | com.android.ide.eclipse.adt.PreCompilerBuilder
15 |
16 |
17 |
18 |
19 | org.eclipse.jdt.core.javabuilder
20 |
21 |
22 |
23 |
24 | com.android.ide.eclipse.adt.ApkBuilder
25 |
26 |
27 |
28 |
29 |
30 | com.android.ide.eclipse.adt.AndroidNature
31 | org.eclipse.jdt.core.javanature
32 |
33 |
34 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Android/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
9 |
10 |
13 |
14 |
19 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Android/ic_launcher-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/WeekendPlanner/Android/ic_launcher-web.png
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Android/libs/android-support-v4.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/WeekendPlanner/Android/libs/android-support-v4.jar
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Android/libs/gson-2.3.1.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/WeekendPlanner/Android/libs/gson-2.3.1.jar
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Android/libs/okhttp-2.4.0.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/WeekendPlanner/Android/libs/okhttp-2.4.0.jar
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Android/libs/okio-1.4.0.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/WeekendPlanner/Android/libs/okio-1.4.0.jar
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Android/libs/retrofit-1.9.0.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/WeekendPlanner/Android/libs/retrofit-1.9.0.jar
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Android/proguard-project.txt:
--------------------------------------------------------------------------------
1 | # To enable ProGuard in your project, edit project.properties
2 | # to define the proguard.config property as described in that file.
3 | #
4 | # Add project specific ProGuard rules here.
5 | # By default, the flags in this file are appended to flags specified
6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt
7 | # You can edit the include path and order by changing the ProGuard
8 | # include property in project.properties.
9 | #
10 | # For more details, see
11 | # http://developer.android.com/guide/developing/tools/proguard.html
12 |
13 | # Add any project specific keep options here:
14 |
15 | # If your project uses WebView with JS, uncomment the following
16 | # and specify the fully qualified class name to the JavaScript interface
17 | # class:
18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
19 | # public *;
20 | #}
21 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Android/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system edit
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 | #
10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
12 |
13 | # Project target.
14 | target=android-18
15 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Android/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/WeekendPlanner/Android/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Android/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/WeekendPlanner/Android/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Android/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/WeekendPlanner/Android/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Android/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/WeekendPlanner/Android/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Android/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Android/res/layout/fragment_tripdetail.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
12 |
13 |
20 |
21 |
29 |
30 |
36 |
37 |
38 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Android/res/layout/row_basicstring.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Android/res/layout/row_day.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
13 |
14 |
21 |
22 |
28 |
29 |
30 |
38 |
39 |
45 |
46 |
47 |
55 |
56 |
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Android/res/menu/main.xml:
--------------------------------------------------------------------------------
1 |
12 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Android/res/values-v11/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Android/res/values-v14/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Android/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 | 64dp
9 |
10 |
11 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Android/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 16dp
5 | 16dp
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Android/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Weekendizer
5 | Settings
6 | Origin City:
7 | What city are you in now?
8 | Budget:
9 | What is your budget?
10 | Destination City:
11 | What city do you want to see?
12 | Enter Destination
13 | Remove Destination
14 | Weekendize
15 |
16 | Weekend Plan
17 | Origin:
18 | Dest:
19 | Depart:
20 | Return:
21 | Departing Flight:
22 | Returning Flight:
23 | Budget:
24 | Flight:
25 |
26 | Remaining:
27 | Ticket Categories:
28 | Place Types:
29 |
30 | Places:
31 | Events:
32 |
33 |
34 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Android/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
14 |
15 |
16 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Android/src/example/web/model/City.java:
--------------------------------------------------------------------------------
1 | package example.web.model;
2 |
3 | import android.os.Parcel;
4 | import android.os.Parcelable;
5 |
6 | import com.google.gson.annotations.SerializedName;
7 |
8 | /**
9 | * A POJO with the relevant fields of a City object from
10 | * the Sabre Flights API
11 | */
12 | public class City implements Parcelable {
13 | @SerializedName("code")
14 | private String mCode;
15 |
16 | @SerializedName("name")
17 | private String mName;
18 |
19 | /**
20 | * Teach the city object to construct itself from
21 | * a parcel made from writeToParcel
22 | */
23 | public City(Parcel source) {
24 | mName = source.readString();
25 | mCode = source.readString();
26 | }
27 |
28 | public String getCode() {
29 | return mCode;
30 | }
31 |
32 | public String getName() {
33 | return mName;
34 | }
35 |
36 | /**
37 | * Required by the Parcelable interface within the Android
38 | * framework. We need to implement parcelable for City because
39 | * we maintain a hashmap in PromptFragment, which requires that
40 | * the class implements parcelable
41 | */
42 | @Override
43 | public int describeContents() {
44 | // No special contents (i.e. FileDescriptors)
45 | return 0;
46 | }
47 |
48 | @Override
49 | public void writeToParcel(Parcel dest, int flags) {
50 | dest.writeString(mName);
51 | dest.writeString(mCode);
52 | }
53 |
54 | public static final Parcelable.Creator
55 | CREATOR = new Creator() {
56 | @Override
57 | public City createFromParcel(Parcel source) {
58 | return new City(source);
59 | }
60 |
61 | @Override
62 | public City[] newArray(int size) {
63 | return new City[size];
64 | }
65 | };
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Android/src/example/web/model/Place.java:
--------------------------------------------------------------------------------
1 | package example.web.model;
2 |
3 | import java.util.List;
4 |
5 | import android.os.Parcel;
6 | import android.os.Parcelable;
7 |
8 | import com.google.gson.annotations.SerializedName;
9 |
10 | import example.web.model.Geocode.Geometry;
11 |
12 | /**
13 | * A POJO representing a place returned from the Google Places API
14 | */
15 | public class Place implements Parcelable {
16 |
17 | @SerializedName("geometry")
18 | private Geometry mLocationCoords;
19 |
20 | @SerializedName("name")
21 | private String mName;
22 |
23 | @SerializedName("types")
24 | private List mTypes;
25 |
26 | public Place(Parcel source) {
27 | mLocationCoords = (Geometry) source.readValue(null);
28 | mName = source.readString();
29 | mTypes = source.createStringArrayList();
30 | }
31 |
32 | public String getName() {
33 | return mName;
34 | }
35 |
36 | public String getType() {
37 | return mTypes.get(0);
38 | }
39 |
40 | @Override
41 | public String toString() {
42 | return mName;
43 | }
44 |
45 | /**
46 | * Required by the Parcelable interface within the Android
47 | * framework.
48 | */
49 | @Override
50 | public int describeContents() {
51 | // No special contents (i.e. FileDescriptors)
52 | return 0;
53 | }
54 |
55 | @Override
56 | public void writeToParcel(Parcel dest, int flags) {
57 | dest.writeValue(mLocationCoords);
58 | dest.writeString(mName);
59 | dest.writeStringList(mTypes);
60 | }
61 |
62 | public static final Parcelable.Creator
63 | CREATOR = new Creator() {
64 | @Override
65 | public Place createFromParcel(Parcel source) {
66 | return new Place(source);
67 | }
68 |
69 | @Override
70 | public Place[] newArray(int size) {
71 | return new Place[size];
72 | }
73 | };
74 |
75 | }
76 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Android/src/example/web/requests/WeekendPlannerRequest.java:
--------------------------------------------------------------------------------
1 | package example.web.requests;
2 |
3 | import com.google.gson.annotations.SerializedName;
4 |
5 | import example.web.model.City;
6 |
7 | /**
8 | * The POJO representing the request from the client
9 | */
10 | public class WeekendPlannerRequest {
11 |
12 | /**
13 | * The initial budget given by the user
14 | */
15 | @SerializedName("budget")
16 | private String mBudget;
17 |
18 | /**
19 | * The current city of the user
20 | */
21 | @SerializedName("currentCity")
22 | private City mOriginCity;
23 |
24 | /**
25 | * The desired destination of the user
26 | */
27 | @SerializedName("destinationCity")
28 | private City mDestinationCity;
29 |
30 | public WeekendPlannerRequest(String budget, City origin,
31 | City destination) {
32 | mBudget = budget;
33 | mOriginCity = origin;
34 | mDestinationCity = destination;
35 | }
36 |
37 | public Double getBudget() {
38 | return Double.valueOf(mBudget);
39 | }
40 |
41 | public City getOriginCity() {
42 | return mOriginCity;
43 | }
44 |
45 | public City getDestinationCity() {
46 | return mDestinationCity;
47 | }
48 |
49 | public String toString() {
50 | return "{budget: " + mBudget
51 | + ", curCity: "
52 | + mOriginCity.getName() + " (" + mOriginCity.getCode() + ")"
53 | + ", destCity: "
54 | + (mDestinationCity == null ?
55 | "null" :
56 | mDestinationCity.getName() + " (" + mDestinationCity.getCode() + ")")
57 | + "}";
58 | }
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Android/src/example/web/responses/CityResponse.java:
--------------------------------------------------------------------------------
1 | package example.web.responses;
2 |
3 | import java.util.List;
4 |
5 | import android.os.Parcel;
6 | import android.os.Parcelable;
7 |
8 | import com.google.gson.annotations.SerializedName;
9 |
10 | import example.web.model.City;
11 |
12 | public class CityResponse implements Parcelable {
13 |
14 | /**
15 | * The list of available cities from the Sabre flights API
16 | */
17 | @SerializedName("Cities")
18 | private List mCities;
19 |
20 | /**
21 | * The error message from the server to display to the
22 | * user via a Toast in the case of an exception
23 | */
24 | private String mError;
25 |
26 | public CityResponse() {
27 | mCities = null;
28 | mError = null;
29 | }
30 |
31 | /**
32 | * Teach the CityResponse how to create
33 | * itself from a parcel created in writeToParcel()
34 | */
35 | @SuppressWarnings("unchecked")
36 | public CityResponse(Parcel source) {
37 | mCities = (List) source.readValue(null);
38 | }
39 |
40 | public List getCities() {
41 | return mCities;
42 | }
43 |
44 | public CityResponse setError(String errorMessage) {
45 | mError = errorMessage;
46 | return this;
47 | }
48 |
49 | public String getError() {
50 | return mError;
51 | }
52 |
53 | /**
54 | * Required by the Parcelable interface within the Android
55 | * framework
56 | */
57 | @Override
58 | public int describeContents() {
59 | // No special contents (i.e. FileDescriptors)
60 | return 0;
61 | }
62 |
63 | @Override
64 | public void writeToParcel(Parcel dest, int flags) {
65 | dest.writeValue(mCities);
66 | }
67 |
68 | public static final Parcelable.Creator
69 | CREATOR = new Creator() {
70 | @Override
71 | public CityResponse createFromParcel(Parcel source) {
72 | return new CityResponse(source);
73 | }
74 |
75 | @Override
76 | public CityResponse[] newArray(int size) {
77 | return new CityResponse[size];
78 | }
79 | };
80 |
81 | }
82 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Android/src/example/web/services/WeekendPlannerService.java:
--------------------------------------------------------------------------------
1 | package example.web.services;
2 |
3 | import example.web.requests.WeekendPlannerRequest;
4 | import example.web.responses.CityResponse;
5 | import example.web.responses.WeekendPlannerResponse;
6 | import retrofit.http.Body;
7 | import retrofit.http.GET;
8 | import retrofit.http.POST;
9 | import retrofit.http.Query;
10 |
11 | public interface WeekendPlannerService {
12 |
13 | @GET("/WeekendPlannerServlet")
14 | CityResponse queryCities(@Query("country") String country);
15 |
16 | @POST("/WeekendPlannerServlet")
17 | WeekendPlannerResponse weekendize(@Body WeekendPlannerRequest request);
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Android/src/example/web/utils/RetrofitAdapterUtils.java:
--------------------------------------------------------------------------------
1 | package example.web.utils;
2 |
3 | import retrofit.RestAdapter;
4 | import retrofit.RestAdapter.LogLevel;
5 | import retrofit.android.AndroidLog;
6 | import retrofit.client.OkClient;
7 |
8 | import com.squareup.okhttp.OkHttpClient;
9 |
10 | import example.web.services.WeekendPlannerService;
11 |
12 | public class RetrofitAdapterUtils {
13 |
14 | public static WeekendPlannerService makeWeekendPlannerService() {
15 | OkHttpClient client = new OkHttpClient();
16 | RestAdapter weekendPlannerAdapter =
17 | new RestAdapter.Builder()
18 | .setClient(new OkClient(client))
19 | .setLogLevel(LogLevel.FULL)
20 | .setLog(new AndroidLog("MYREQUESTS"))
21 | .setEndpoint("http://10.0.3.2:8080/WeekendPlanner/")
22 | .build();
23 | return weekendPlannerAdapter.create(WeekendPlannerService.class);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Server/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Server/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | WeekendPlanner
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.wst.jsdt.core.javascriptValidator
10 |
11 |
12 |
13 |
14 | org.eclipse.jdt.core.javabuilder
15 |
16 |
17 |
18 |
19 | org.eclipse.wst.common.project.facet.core.builder
20 |
21 |
22 |
23 |
24 | org.eclipse.wst.validation.validationbuilder
25 |
26 |
27 |
28 |
29 |
30 | org.eclipse.jem.workbench.JavaEMFNature
31 | org.eclipse.wst.common.modulecore.ModuleCoreNature
32 | org.eclipse.wst.common.project.facet.core.nature
33 | org.eclipse.jdt.core.javanature
34 | org.eclipse.wst.jsdt.core.jsNature
35 |
36 |
37 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Server/WebContent/META-INF/MANIFEST.MF:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | Class-Path:
3 |
4 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Server/WebContent/WEB-INF/lib/gson-2.3.1.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/WeekendPlanner/Server/WebContent/WEB-INF/lib/gson-2.3.1.jar
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Server/WebContent/WEB-INF/lib/retrofit-1.9.0.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascraigschmidt/CS892/b5a21fd5cd9141c757dc23368fc0ccdaa698c297/ex/WeekendPlanner/Server/WebContent/WEB-INF/lib/retrofit-1.9.0.jar
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Server/src/example/web/model/City.java:
--------------------------------------------------------------------------------
1 | package example.web.model;
2 |
3 | import com.google.gson.annotations.SerializedName;
4 |
5 | /**
6 | * A POJO with the relevant fields of a City object from
7 | * the Sabre Flights API
8 | */
9 | public class City {
10 | @SerializedName("code")
11 | private String mCode;
12 |
13 | @SerializedName("name")
14 | private String mName;
15 |
16 | public String getCode() {
17 | return mCode;
18 | }
19 |
20 | public String getName() {
21 | return mName;
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Server/src/example/web/model/Geocode.java:
--------------------------------------------------------------------------------
1 | package example.web.model;
2 |
3 | import com.google.gson.annotations.SerializedName;
4 |
5 | /**
6 | * A POJO representing the relevant fields of a geocode of a city
7 | * from the Google Geocode API
8 | */
9 | public class Geocode {
10 |
11 | @SerializedName("geometry")
12 | private Geometry mLocationCoords;
13 |
14 | public String getLat() {
15 | return mLocationCoords.getLat();
16 | }
17 |
18 | public String getLng() {
19 | return mLocationCoords.getLng();
20 | }
21 |
22 | public String toString() {
23 | return "{" + getLat() + "," + getLng() + "}";
24 | }
25 |
26 | /**
27 | * A nested POJO upon which the Geocode POJO relies
28 | */
29 | public class Geometry {
30 |
31 | @SerializedName("location")
32 | private LatLng mLocation;
33 |
34 | public String getLat() {
35 | return mLocation.getLat();
36 | }
37 |
38 | public String getLng() {
39 | return mLocation.getLng();
40 | }
41 | }
42 |
43 | /**
44 | * A nested POJO upon which the Geocode POJO relies
45 | */
46 | public class LatLng {
47 |
48 | @SerializedName("lat")
49 | private String mLat;
50 |
51 | @SerializedName("lng")
52 | private String mLng;
53 |
54 | public String getLat() {
55 | return mLat;
56 | }
57 |
58 | public String getLng() {
59 | return mLng;
60 | }
61 | }
62 |
63 | }
64 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Server/src/example/web/model/Place.java:
--------------------------------------------------------------------------------
1 | package example.web.model;
2 |
3 | import java.util.List;
4 |
5 | import com.google.gson.annotations.SerializedName;
6 |
7 | import example.web.model.Geocode.Geometry;
8 |
9 | /**
10 | * A POJO representing a place returned from the Google Places API
11 | */
12 | public class Place {
13 |
14 | @SerializedName("geometry")
15 | private Geometry mLocationCoords;
16 |
17 | @SerializedName("name")
18 | private String mName;
19 |
20 | @SerializedName("types")
21 | private List mTypes;
22 |
23 | public String getName() {
24 | return mName;
25 | }
26 |
27 | public String getType() {
28 | return mTypes.get(0);
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Server/src/example/web/model/Weather.java:
--------------------------------------------------------------------------------
1 | package example.web.model;
2 |
3 | import java.util.List;
4 |
5 | import com.google.gson.annotations.SerializedName;
6 |
7 | /**
8 | * A POJO that includes the relevant fields of the
9 | * Weather object from the OpenWeatherMap API necessary
10 | * to the WeekendResponse
11 | */
12 | public class Weather {
13 |
14 | @SerializedName("temp")
15 | private Temperature mTemperature;
16 |
17 | @SerializedName("weather")
18 | private List mConditions;
19 |
20 | public Double getDayTemperature() {
21 | return mTemperature.getDayTemperature();
22 | }
23 |
24 | public String getDayCondition() {
25 | return mConditions.get(0).getCondition();
26 | }
27 |
28 | @Override
29 | public String toString() {
30 | return "Temperature: " + mTemperature + "F, Conditions:" + mConditions;
31 | }
32 |
33 | /**
34 | * A nested POJO upon which the Weather object relies
35 | */
36 | public class Temperature {
37 |
38 | @SerializedName("day")
39 | private Double mDayTemperature;
40 |
41 | public Double getDayTemperature() {
42 | return mDayTemperature;
43 | }
44 |
45 | public String toString() {
46 | return mDayTemperature.toString();
47 | }
48 | }
49 |
50 | /**
51 | * A nested POJO upon which the Weather object relies
52 | */
53 | public class Condition {
54 |
55 | @SerializedName("main")
56 | private String mCondition;
57 |
58 | public String getCondition() {
59 | return mCondition;
60 | }
61 |
62 | public String toString() {
63 | return mCondition;
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Server/src/example/web/ops/BaseOps.java:
--------------------------------------------------------------------------------
1 | package example.web.ops;
2 |
3 | import example.web.responses.OAuth2TokenResponse;
4 | import example.web.utils.NoAuthUtils;
5 | import example.web.utils.BaseOAuth2Utils;
6 | import retrofit.RestAdapter;
7 | import retrofit.RestAdapter.LogLevel;
8 | import retrofit.client.UrlConnectionClient;
9 |
10 | /**
11 | * Provides common members and functionality that
12 | * each class that interacts with an API probably needs
13 | */
14 | public abstract class BaseOps {
15 |
16 | /**
17 | * The endpoint of the API being queried
18 | */
19 | protected String mEndpoint;
20 |
21 | /**
22 | * The Retrofit service that handles querying the API
23 | */
24 | protected T mService;
25 |
26 | /**
27 | * The required Authorization utilities if necessary
28 | */
29 | protected BaseOAuth2Utils mAuthUtils;
30 |
31 | protected BaseOps(String endpoint, Class serviceClass) {
32 | init(endpoint, serviceClass, null);
33 | }
34 |
35 | protected BaseOps(String endpoint,
36 | Class serviceClass, BaseOAuth2Utils authUtils) {
37 | init(endpoint, serviceClass, authUtils);
38 | }
39 |
40 | private void init(String endpoint, Class serviceClass,
41 | BaseOAuth2Utils authUtils) {
42 | mEndpoint = endpoint;
43 | mService = makeService(serviceClass);
44 | mAuthUtils = authUtils != null ? authUtils : new NoAuthUtils();
45 | }
46 |
47 | public String getEndpoint() {
48 | return mEndpoint;
49 | }
50 |
51 | /**
52 | * Provides the common structure for an OAuth2 token
53 | * i.e. "Bearer "
54 | */
55 | public String getAuthToken() {
56 | return mAuthUtils.makeBearerToken(authorize().getAccessToken());
57 | }
58 |
59 | /**
60 | * Allows the way that each API is authorized to be tailored
61 | * to the specific API
62 | */
63 | protected abstract OAuth2TokenResponse authorize();
64 |
65 | public BaseOAuth2Utils getAuthUtils() {
66 | return mAuthUtils;
67 | }
68 |
69 | public T getService() {
70 | return mService;
71 | }
72 |
73 | private T makeService(Class serviceClass) {
74 | return new RestAdapter.Builder()
75 | .setClient(new UrlConnectionClient())
76 | .setEndpoint(mEndpoint)
77 | //.setLogLevel(LogLevel.FULL)
78 | .build()
79 | .create(serviceClass);
80 | }
81 |
82 | /**
83 | * Helper method to identify the execution order of the pipeline
84 | * operations
85 | */
86 | protected void logExecutionTime(String method) {
87 | System.out.println(method + " - "
88 | + System.currentTimeMillis() % 100000);
89 | }
90 |
91 | }
92 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Server/src/example/web/ops/TicketOps.java:
--------------------------------------------------------------------------------
1 | package example.web.ops;
2 |
3 | import retrofit.RetrofitError;
4 | import example.web.responses.OAuth2TokenResponse;
5 | import example.web.responses.TicketResponse;
6 | import example.web.services.TicketService;
7 | import example.web.utils.BaseOAuth2Utils;
8 | import example.web.utils.TicketAuthUtils;
9 |
10 | /**
11 | * Provides API-specific constants and an interface to interact
12 | * with the StubHub API
13 | */
14 | public class TicketOps extends BaseOps {
15 |
16 | /**
17 | * Default values
18 | */
19 | private final String MIN_AVAILABLE = "1";
20 | private final String FIELD_LIST =
21 | "title, dateLocal, ticketInfo, venue, categories, groupings";
22 | private final String SORT = "dateLocal asc, minPrice desc";
23 | private final String LIMIT = "500";
24 |
25 | public TicketOps(String endpoint) {
26 | super(endpoint, TicketService.class, new TicketAuthUtils());
27 | }
28 |
29 | /**
30 | * Authorizes the StubHub query, which requires only the provided
31 | * app token, and therefore does not need an additional authorize query
32 | * like what is required for the Sabre API calls
33 | */
34 | @Override
35 | protected OAuth2TokenResponse authorize() {
36 | logExecutionTime("TicketOps::authorize");
37 | return new OAuth2TokenResponse(
38 | mAuthUtils.makeCredential(BaseOAuth2Utils.APP_TOKEN));
39 | }
40 |
41 | /**
42 | * Queries the StubHub API for tickets to events in the given
43 | * destination city in the given time range, at no higher than
44 | * the maximum price
45 | */
46 | public TicketResponse getTickets(String authToken,
47 | String dateTimeRange, String city, String maxPrice) {
48 | logExecutionTime("TicketOps::getTickets");
49 | try {
50 | return mService.queryTickets(
51 | authToken,
52 | dateTimeRange,
53 | city,
54 | maxPrice,
55 | MIN_AVAILABLE,
56 | FIELD_LIST,
57 | SORT,
58 | LIMIT);
59 | } catch (RetrofitError e) {
60 | // Catch and further detail the Retrofit error
61 | throw new RuntimeException(
62 | "Error getting tickets: "
63 | + "There are likely no event postings this weekend in "
64 | + city);
65 | }
66 | }
67 |
68 | }
69 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Server/src/example/web/ops/WeatherOps.java:
--------------------------------------------------------------------------------
1 | package example.web.ops;
2 |
3 | import retrofit.RetrofitError;
4 | import example.web.responses.OAuth2TokenResponse;
5 | import example.web.responses.WeatherResponse;
6 | import example.web.services.WeatherService;
7 |
8 | /**
9 | * Provides API-specific constants and an interface to interact
10 | * with the OpenWeatherMaps API
11 | */
12 | public class WeatherOps extends BaseOps {
13 |
14 | /**
15 | * Default values
16 | */
17 | private final String UNITS = "imperial";
18 | private final String RESPONSE_MODE = "json";
19 |
20 | public WeatherOps(String endpoint) {
21 | super(endpoint, WeatherService.class);
22 | }
23 |
24 | /**
25 | * Override the authorize () abstract method, which in this case
26 | * is a no-op, because the OpenWeatherMap forecast is an unauthorized API call
27 | */
28 | @Override
29 | protected OAuth2TokenResponse authorize() {
30 | logExecutionTime("WeatherOps::authorize");
31 | // no-op for non-authorized APIs
32 | return null;
33 | }
34 |
35 | /**
36 | * Invoke the WeatherService retrofit adapter to query the endpoint
37 | * for the weather forecast
38 | */
39 | public WeatherResponse getWeather(String city, Integer dayCount) {
40 | logExecutionTime("WeatherOps::getWeather");
41 | try {
42 | return mService.queryWeather(
43 | city,
44 | dayCount,
45 | UNITS,
46 | RESPONSE_MODE);
47 | } catch (RetrofitError e) {
48 | // Catch and further detail the Retrofit error
49 | throw new RuntimeException(
50 | "Error getting weather: "
51 | + "The service is likely down");
52 | }
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Server/src/example/web/requests/WeekendPlannerRequest.java:
--------------------------------------------------------------------------------
1 | package example.web.requests;
2 |
3 | import com.google.gson.annotations.SerializedName;
4 |
5 | import example.web.model.City;
6 |
7 | /**
8 | * The POJO representing the request from the client
9 | */
10 | public class WeekendPlannerRequest {
11 |
12 | /**
13 | * The initial budget given by the user
14 | */
15 | @SerializedName("budget")
16 | private String mBudget;
17 |
18 | /**
19 | * The current city of the user
20 | */
21 | @SerializedName("currentCity")
22 | private City mOriginCity;
23 |
24 | /**
25 | * The desired destination of the user
26 | */
27 | @SerializedName("destinationCity")
28 | private City mDestinationCity;
29 |
30 | public Double getBudget() {
31 | return Double.valueOf(mBudget);
32 | }
33 |
34 | public City getOriginCity() {
35 | return mOriginCity;
36 | }
37 |
38 | public City getDestinationCity() {
39 | return mDestinationCity;
40 | }
41 |
42 | public String toString() {
43 | return "{budget: " + mBudget
44 | + ", curCity: "
45 | + mOriginCity.getName() + " (" + mOriginCity.getCode() + ")"
46 | + ", destCity: "
47 | + (mDestinationCity == null ?
48 | "null" :
49 | mDestinationCity.getName() + " (" + mDestinationCity.getCode() + ")")
50 | + "}";
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Server/src/example/web/responses/CityResponse.java:
--------------------------------------------------------------------------------
1 | package example.web.responses;
2 |
3 | import java.util.List;
4 |
5 | import com.google.gson.annotations.SerializedName;
6 |
7 | import example.web.model.City;
8 |
9 | /**
10 | * The top-level POJO returned by the Sabre Cities API.
11 | * This class needs no accessor methods because the response is
12 | * passed directly on to the client which does the processing
13 | */
14 | public class CityResponse {
15 |
16 | /**
17 | * The valid cities for which flights may exist between
18 | */
19 | @SerializedName("Cities")
20 | private List mCities;
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Server/src/example/web/responses/GeoCodeResponse.java:
--------------------------------------------------------------------------------
1 | package example.web.responses;
2 |
3 | import java.util.List;
4 |
5 | import com.google.gson.annotations.SerializedName;
6 |
7 | import example.web.model.Geocode;
8 |
9 | /**
10 | * The top-level POJO returned by the Google Geocode API
11 | */
12 | public class GeoCodeResponse {
13 |
14 | /**
15 | * The Geocoding response
16 | */
17 | @SerializedName("results")
18 | private List mGeocodes;
19 |
20 | public String getLat() {
21 | return mGeocodes.get(0).getLat();
22 | }
23 |
24 | public String getLng() {
25 | return mGeocodes.get(0).getLng();
26 | }
27 |
28 | public String toString() {
29 | return mGeocodes.toString();
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Server/src/example/web/responses/OAuth2TokenResponse.java:
--------------------------------------------------------------------------------
1 | package example.web.responses;
2 |
3 | import com.google.gson.annotations.SerializedName;
4 |
5 | /**
6 | * The top-level POJO returned commonly by OAuth2 requests
7 | */
8 | public class OAuth2TokenResponse {
9 |
10 | /**
11 | * The access credential returned by the server
12 | */
13 | @SerializedName("access_token")
14 | private String mAccessToken;
15 |
16 | /**
17 | * The token type
18 | */
19 | @SerializedName("token_type")
20 | private String mTokenType;
21 |
22 | /**
23 | * The life span of the token
24 | */
25 | @SerializedName("expires_in")
26 | private String mExpiresIn;
27 |
28 | public OAuth2TokenResponse(String credential) {
29 | mAccessToken = credential;
30 | }
31 |
32 | public String getAccessToken() {
33 | return mAccessToken;
34 | }
35 |
36 | public String toString() {
37 | return mAccessToken
38 | + " {type: " + mTokenType
39 | + ", expires: " + mExpiresIn + "}";
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Server/src/example/web/responses/PlacesResponse.java:
--------------------------------------------------------------------------------
1 | package example.web.responses;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 | import java.util.Random;
6 | import java.util.stream.Collectors;
7 |
8 | import com.google.gson.annotations.SerializedName;
9 |
10 | import example.web.model.Place;
11 |
12 | /**
13 | * The top-level POJO returned by the Google Places API
14 | */
15 | public class PlacesResponse {
16 |
17 | /**
18 | * Default values
19 | */
20 | private final Integer NUM_PLACES = 5;
21 |
22 | /**
23 | * The places returned by the query
24 | */
25 | @SerializedName("results")
26 | private List mPlaces;
27 |
28 | public List getPlaces() {
29 | return mPlaces;
30 | }
31 |
32 | /**
33 | * Selects and returns NUM_PLACES places at random in a list
34 | */
35 | public List getRandomPlaces() {
36 | List ret = new ArrayList(
37 | new Random().ints(0, mPlaces.size())
38 | .mapToObj(mPlaces::get)
39 | .limit(NUM_PLACES)
40 | .collect(Collectors.toSet()));
41 | return ret;
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Server/src/example/web/responses/TicketResponse.java:
--------------------------------------------------------------------------------
1 | package example.web.responses;
2 |
3 | import java.util.List;
4 |
5 | import com.google.gson.annotations.SerializedName;
6 |
7 | import example.web.model.Event;
8 |
9 | /**
10 | * The top-level POJO returned by the StubHub API
11 | */
12 | public class TicketResponse {
13 |
14 | /**
15 | * The events returned by the query
16 | */
17 | @SerializedName("events")
18 | private List mEvents;
19 |
20 | public List getEvents() {
21 | return mEvents;
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Server/src/example/web/responses/WeatherResponse.java:
--------------------------------------------------------------------------------
1 | package example.web.responses;
2 |
3 | import java.util.List;
4 |
5 | import com.google.gson.annotations.SerializedName;
6 |
7 | import example.web.model.Weather;
8 |
9 | /**
10 | * The top-level POJO returned by the OpenWeatherMap API
11 | */
12 | public class WeatherResponse {
13 |
14 | /**
15 | * Default values
16 | */
17 | private static final Integer WEEKEND_LENGTH = 3;
18 |
19 | /**
20 | * List representing the forecasts of each day
21 | */
22 | @SerializedName("list")
23 | private List mWeather;
24 |
25 | /**
26 | * Returns only the final 3 or less days of the response, which
27 | * will always represent the days relevant to the weekend
28 | */
29 | public List getWeekendWeather() {
30 | return mWeather.size() > WEEKEND_LENGTH ?
31 | mWeather.subList(
32 | mWeather.size() - WEEKEND_LENGTH, mWeather.size()) :
33 | mWeather;
34 | }
35 |
36 | public String toString() {
37 | return "Weekend Forecast: " + getWeekendWeather();
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Server/src/example/web/services/FlightService.java:
--------------------------------------------------------------------------------
1 | package example.web.services;
2 |
3 | import example.web.responses.OAuth2TokenResponse;
4 | import example.web.responses.CityResponse;
5 | import example.web.responses.FlightResponse;
6 | import retrofit.http.Field;
7 | import retrofit.http.FormUrlEncoded;
8 | import retrofit.http.GET;
9 | import retrofit.http.Header;
10 | import retrofit.http.POST;
11 | import retrofit.http.Query;
12 |
13 | /**
14 | * The Retrofit service that interacts with the Sabre Flights API
15 | */
16 | public interface FlightService {
17 |
18 | @FormUrlEncoded
19 | @POST("/v1/auth/token")
20 | OAuth2TokenResponse authorize(
21 | @Header("Authorization") String auth,
22 | @Field("grant_type") String value);
23 |
24 | @GET("/v1/lists/supported/cities")
25 | CityResponse queryCities(
26 | @Header("Authorization") String token,
27 | @Query("country") String country);
28 |
29 | @GET("/v1/shop/flights")
30 | FlightResponse queryFlights(
31 | @Header("Authorization") String token,
32 | @Query("origin") String origin,
33 | @Query("destination") String destination,
34 | @Query("departuredate") String departureDate,
35 | @Query("returndate") String returnDate,
36 | @Query("maxfare") String maxFare,
37 | @Query("outbounddeparturewindow") String departureWindow,
38 | @Query("inboundarrivalwindow") String returnWindow,
39 | @Query("limit") String limitResponses);
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Server/src/example/web/services/PlacesService.java:
--------------------------------------------------------------------------------
1 | package example.web.services;
2 |
3 | import example.web.responses.GeoCodeResponse;
4 | import example.web.responses.PlacesResponse;
5 | import retrofit.http.GET;
6 | import retrofit.http.Query;
7 |
8 | /**
9 | * The Retrofit service that interacts with the Google Places API
10 | */
11 | public interface PlacesService {
12 |
13 | @GET("/maps/api/place/nearbysearch/json")
14 | PlacesResponse queryPlaces(
15 | @Query("key") String authToken,
16 | @Query("location") String latLngCoords,
17 | @Query("radius") Integer meters,
18 | @Query("types") String types);
19 |
20 | @GET("/maps/api/geocode/json")
21 | GeoCodeResponse queryGeocode(
22 | @Query("key") String authToken,
23 | @Query("address") String city);
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Server/src/example/web/services/TicketService.java:
--------------------------------------------------------------------------------
1 | package example.web.services;
2 |
3 | import retrofit.http.Field;
4 | import retrofit.http.FormUrlEncoded;
5 | import retrofit.http.GET;
6 | import retrofit.http.Header;
7 | import retrofit.http.POST;
8 | import retrofit.http.Query;
9 | import example.web.responses.OAuth2TokenResponse;
10 | import example.web.responses.TicketResponse;
11 |
12 | /**
13 | * The Retrofit service that interacts with the StubHub API
14 | */
15 | public interface TicketService {
16 |
17 | @FormUrlEncoded
18 | @POST("/login")
19 | OAuth2TokenResponse authorize(
20 | @Header("Authorization") String auth,
21 | @Field("grant_type") String grantType,
22 | @Field("username") String username,
23 | @Field("password") String password,
24 | @Field("scope") String scope);
25 |
26 | @GET("/search/catalog/events/v2")
27 | TicketResponse queryTickets(
28 | @Header("Authorization") String auth,
29 | @Query("date") String dateRange,
30 | @Query("city") String city,
31 | @Query("maxPrice") String maxPrice,
32 | @Query("minTicketsAvailable") String minAvailable,
33 | @Query("fieldList") String fieldList,
34 | @Query("sort") String sort,
35 | @Query("limit") String limit);
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Server/src/example/web/services/WeatherService.java:
--------------------------------------------------------------------------------
1 | package example.web.services;
2 |
3 | import example.web.responses.WeatherResponse;
4 | import retrofit.http.GET;
5 | import retrofit.http.Query;
6 |
7 | /**
8 | * The Retrofit service that interacts with the OpenWeatherMaps API
9 | */
10 | public interface WeatherService {
11 |
12 | @GET("/data/2.5/forecast/daily")
13 | WeatherResponse queryWeather(
14 | @Query("q") String city,
15 | @Query("cnt") Integer dayCount,
16 | @Query("units") String units,
17 | @Query("mode") String responseMode);
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Server/src/example/web/utils/BaseOAuth2Utils.java:
--------------------------------------------------------------------------------
1 | package example.web.utils;
2 |
3 | import java.util.Base64;
4 | import java.util.Base64.Encoder;
5 |
6 | /**
7 | * Utility base class to provide common functionality needed to
8 | * interact with many different APIs that implement the OAuth2
9 | * authorization protocol with various API-specific details
10 | */
11 | public abstract class BaseOAuth2Utils {
12 |
13 | private final static Encoder mBase64Encoder = Base64.getEncoder();
14 | public final static int APP_TOKEN = 0;
15 | public final static int USER_TOKEN = 1;
16 |
17 | /**
18 | * Commonly used parameters and request headers for
19 | * interacting with an OAuth2 protected API
20 | */
21 | protected String mClientKey;
22 | protected String mClientSecret;
23 | protected String mApplicationKey;
24 | protected Boolean mIsPreEncoded;
25 | protected String mGrantType;
26 | protected String mUsername;
27 | protected String mPassword;
28 | protected String mScope;
29 |
30 | /**
31 | * Makes a credential based on the type of token needed
32 | * and whether the provided credential is already base64 encoded
33 | */
34 | public String makeCredential(Integer tokenType) {
35 | switch(tokenType) {
36 | case APP_TOKEN:
37 | return encodeIfNecessary(mApplicationKey);
38 | case USER_TOKEN:
39 | String cred =
40 | encodeIfNecessary(mClientKey)
41 | + ":"
42 | + encodeIfNecessary(mClientSecret);
43 |
44 | return "Basic " + mBase64Encoder.encodeToString(cred.getBytes());
45 | default:
46 | // throw tokenTypeNotSupported Exception
47 | return null;
48 | }
49 | }
50 |
51 | private String encodeIfNecessary(String target) {
52 | return !mIsPreEncoded ?
53 | mBase64Encoder.encodeToString(target.getBytes())
54 | : target;
55 | }
56 |
57 | public String makeBearerToken(String authToken) {
58 | return "Bearer " + authToken;
59 | }
60 |
61 | public String getGrantType() {
62 | return mGrantType;
63 | }
64 |
65 | public String getUsername() {
66 | return mUsername;
67 | }
68 |
69 | public String getPassword() {
70 | return mPassword;
71 | }
72 |
73 | public String getScope() {
74 | return mScope;
75 | }
76 |
77 | }
78 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Server/src/example/web/utils/DateUtils.java:
--------------------------------------------------------------------------------
1 | package example.web.utils;
2 |
3 | import java.time.DayOfWeek;
4 | import java.time.LocalDate;
5 | import java.time.Period;
6 | import java.time.format.DateTimeFormatter;
7 | import java.time.temporal.TemporalAdjusters;
8 |
9 | import example.web.model.Flight;
10 |
11 | /**
12 | * A utility class to compute appropriate times and time ranges
13 | */
14 | public class DateUtils {
15 |
16 | public static String getFormattedDateOfNext(DayOfWeek day) {
17 | return getDateOfNext(day)
18 | .format(DateTimeFormatter.ISO_LOCAL_DATE);
19 | }
20 |
21 | private static LocalDate getDateOfNext(DayOfWeek day) {
22 | LocalDate today = LocalDate.now();
23 | return day == DayOfWeek.FRIDAY ?
24 | today.with(TemporalAdjusters.nextOrSame(day)) :
25 | today.plusDays(1).with(TemporalAdjusters.next(day));
26 | }
27 |
28 | public static String makeDateTimeRange(Flight flight) {
29 | return removeSeconds(flight.getDepartingArrivalDateTime())
30 | + " TO "
31 | + removeSeconds(flight.getReturningDepartureDateTime());
32 | }
33 |
34 | public static Integer getNumDaysUntilNext(DayOfWeek day) {
35 | LocalDate today = LocalDate.now();
36 | return Period.between(today, getDateOfNext(day)).getDays()
37 | + (today.getDayOfWeek().compareTo(DayOfWeek.FRIDAY) > 0 ? 7 : 0);
38 | }
39 |
40 | private static String removeSeconds(String dateTime) {
41 | return dateTime.substring(0, dateTime.lastIndexOf(":"));
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Server/src/example/web/utils/FlightAuthUtils.java:
--------------------------------------------------------------------------------
1 | package example.web.utils;
2 |
3 | /**
4 | * The specific credential information for the Sabre Flights API
5 | */
6 | public class FlightAuthUtils extends BaseOAuth2Utils {
7 |
8 | {
9 | mClientKey = "V1:1yp9p698tnoko3to:DEVCENTER:EXT";
10 | mClientSecret = "26ktVdFH";
11 | mApplicationKey = null;
12 | mIsPreEncoded = false;
13 | mGrantType = "client_credentials";
14 | mUsername = null;
15 | mPassword = null;
16 | mScope = null;
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Server/src/example/web/utils/NoAuthUtils.java:
--------------------------------------------------------------------------------
1 | package example.web.utils;
2 |
3 | /**
4 | * A "no-op" class For APIs with no authorization requirements
5 | */
6 | public class NoAuthUtils extends BaseOAuth2Utils {
7 |
8 | {
9 | mClientKey = null;
10 | mClientSecret = null;
11 | mApplicationKey = null;
12 | mIsPreEncoded = null;
13 | mGrantType = null;
14 | mUsername = null;
15 | mPassword = null;
16 | mScope = null;
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Server/src/example/web/utils/PlacesAuthUtils.java:
--------------------------------------------------------------------------------
1 | package example.web.utils;
2 |
3 | /**
4 | * The specific credential information for the Google Places API
5 | */
6 | public class PlacesAuthUtils extends BaseOAuth2Utils {
7 |
8 | {
9 | mClientKey = null;
10 | mClientSecret = null;
11 | mApplicationKey = "AIzaSyARtwglLWxeg7HCXaC5eabyLwX3rSSANnY";
12 | mIsPreEncoded = true;
13 | mGrantType = null;
14 | mUsername = null;
15 | mPassword = null;
16 | mScope = null;
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/ex/WeekendPlanner/Server/src/example/web/utils/TicketAuthUtils.java:
--------------------------------------------------------------------------------
1 | package example.web.utils;
2 |
3 | /**
4 | * The specific credential information for the StubHub API
5 | */
6 | public class TicketAuthUtils extends BaseOAuth2Utils {
7 |
8 | {
9 | mClientKey = "4zwpG09zanoQX79_SyuqqbgAsEIa";
10 | mClientSecret = "9tDFugiYuan5W9EgCmHFhj_Wm0sa";
11 | mApplicationKey = "kh6SoqldYKQd2z4oGueclY5mGaMa";
12 | mIsPreEncoded = true;
13 | mGrantType = "password";
14 | mUsername = "nolan.m.smith@vanderbilt.edu";
15 | mPassword = "testPass123";
16 | mScope = "SANDBOX";
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------