Browse Source

adding cs240

master
Derek McQuay 3 years ago
parent
commit
9d4aab12b8
100 changed files with 7976 additions and 0 deletions
  1. +2
    -0
      cs240/record-indexer/.gitignore
  2. +1
    -0
      cs240/record-indexer/.idea/.name
  3. +17
    -0
      cs240/record-indexer/.idea/artifacts/search_gui_jar.xml
  4. +13
    -0
      cs240/record-indexer/.idea/codeStyleSettings.xml
  5. +23
    -0
      cs240/record-indexer/.idea/compiler.xml
  6. +5
    -0
      cs240/record-indexer/.idea/copyright/profiles_settings.xml
  7. +11
    -0
      cs240/record-indexer/.idea/dictionaries/film42.xml
  8. +5
    -0
      cs240/record-indexer/.idea/encodings.xml
  9. +11
    -0
      cs240/record-indexer/.idea/libraries/checkstyle_5_3_all.xml
  10. +15
    -0
      cs240/record-indexer/.idea/libraries/commons_io_2.xml
  11. +11
    -0
      cs240/record-indexer/.idea/libraries/sqlite_jdbc_3_8_0_20130827_035027_1.xml
  12. +28
    -0
      cs240/record-indexer/.idea/misc.xml
  13. +9
    -0
      cs240/record-indexer/.idea/modules.xml
  14. +5
    -0
      cs240/record-indexer/.idea/scopes/scope_settings.xml
  15. +125
    -0
      cs240/record-indexer/.idea/uiDesigner.xml
  16. +7
    -0
      cs240/record-indexer/.idea/vcs.xml
  17. +1427
    -0
      cs240/record-indexer/.idea/workspace.xml
  18. +200
    -0
      cs240/record-indexer/build.xml
  19. +58
    -0
      cs240/record-indexer/checkstyle.xml
  20. +107
    -0
      cs240/record-indexer/src/client/Client.java
  21. +119
    -0
      cs240/record-indexer/src/client/communication/Communicator.java
  22. +20
    -0
      cs240/record-indexer/src/client/communication/errors/RemoteServerErrorException.java
  23. +21
    -0
      cs240/record-indexer/src/client/communication/errors/UnauthorizedAccessException.java
  24. +113
    -0
      cs240/record-indexer/src/client/communication/modules/HttpClient.java
  25. +102
    -0
      cs240/record-indexer/src/client/components/FileMenu.java
  26. +147
    -0
      cs240/record-indexer/src/client/components/MainWindow.java
  27. +74
    -0
      cs240/record-indexer/src/client/components/SplitBase.java
  28. +156
    -0
      cs240/record-indexer/src/client/components/downloadModal/DownloadModal.java
  29. +25
    -0
      cs240/record-indexer/src/client/components/downloadModal/SampleImage.java
  30. +52
    -0
      cs240/record-indexer/src/client/components/downloadModal/SampleImageModal.java
  31. +77
    -0
      cs240/record-indexer/src/client/components/fieldHelp/FieldHelp.java
  32. +141
    -0
      cs240/record-indexer/src/client/components/formEntry/FormEntry.java
  33. +195
    -0
      cs240/record-indexer/src/client/components/formEntry/FormTable.java
  34. +45
    -0
      cs240/record-indexer/src/client/components/imagePanel/ImageCell.java
  35. +174
    -0
      cs240/record-indexer/src/client/components/imagePanel/ImageControl.java
  36. +36
    -0
      cs240/record-indexer/src/client/components/imagePanel/ImagePanel.java
  37. +147
    -0
      cs240/record-indexer/src/client/components/imagePanel/ImageTable.java
  38. +291
    -0
      cs240/record-indexer/src/client/components/imagePanel/ScalableImage.java
  39. +12
    -0
      cs240/record-indexer/src/client/components/imagePanel/listeners/ImageControlsListener.java
  40. +5
    -0
      cs240/record-indexer/src/client/components/listeners/DrawingListener.java
  41. +42
    -0
      cs240/record-indexer/src/client/components/loginWindow/ErrorLoginDialog.java
  42. +74
    -0
      cs240/record-indexer/src/client/components/loginWindow/LoginWindow.java
  43. +53
    -0
      cs240/record-indexer/src/client/components/loginWindow/SuccessLoginDialog.java
  44. +22
    -0
      cs240/record-indexer/src/client/components/menus/SpellCheckPopup.java
  45. +89
    -0
      cs240/record-indexer/src/client/components/spellCheck/SpellingModal.java
  46. +115
    -0
      cs240/record-indexer/src/client/components/tableEntry/EntryCellEditor.java
  47. +58
    -0
      cs240/record-indexer/src/client/components/tableEntry/EntryCellRenderer.java
  48. +65
    -0
      cs240/record-indexer/src/client/components/tableEntry/RecordCellEditor.java
  49. +36
    -0
      cs240/record-indexer/src/client/components/tableEntry/RecordCellRenderer.java
  50. +106
    -0
      cs240/record-indexer/src/client/components/tableEntry/TableEntry.java
  51. +138
    -0
      cs240/record-indexer/src/client/components/tableEntry/TableModel.java
  52. +81
    -0
      cs240/record-indexer/src/client/modules/spellChecker/KnownData.java
  53. +120
    -0
      cs240/record-indexer/src/client/modules/spellChecker/SpellChecker.java
  54. +6
    -0
      cs240/record-indexer/src/client/modules/spellChecker/WordSelectedListener.java
  55. +25
    -0
      cs240/record-indexer/src/client/persistence/Cell.java
  56. +349
    -0
      cs240/record-indexer/src/client/persistence/ImageState.java
  57. +9
    -0
      cs240/record-indexer/src/client/persistence/ImageStateListener.java
  58. +7
    -0
      cs240/record-indexer/src/client/persistence/NewProjectListener.java
  59. +131
    -0
      cs240/record-indexer/src/client/persistence/Settings.java
  60. +11
    -0
      cs240/record-indexer/src/client/persistence/SyncContext.java
  61. +251
    -0
      cs240/record-indexer/src/search/Main.java
  62. +24
    -0
      cs240/record-indexer/src/search/MainLayout.java
  63. +19
    -0
      cs240/record-indexer/src/search/Search.java
  64. +22
    -0
      cs240/record-indexer/src/search/elements/FieldButton.java
  65. +10
    -0
      cs240/record-indexer/src/search/elements/ImageButton.java
  66. +25
    -0
      cs240/record-indexer/src/search/elements/ProjectGroup.java
  67. +10
    -0
      cs240/record-indexer/src/search/forms/InputField.java
  68. +132
    -0
      cs240/record-indexer/src/search/helpers/Networking.java
  69. +25
    -0
      cs240/record-indexer/src/search/helpers/dataModels/ProjectContainer.java
  70. +49
    -0
      cs240/record-indexer/src/server/Server.java
  71. +15
    -0
      cs240/record-indexer/src/server/controllers/UsersController.java
  72. +142
    -0
      cs240/record-indexer/src/server/db/common/Database.java
  73. +10
    -0
      cs240/record-indexer/src/server/db/common/SQL.java
  74. +80
    -0
      cs240/record-indexer/src/server/db/common/Transaction.java
  75. +235
    -0
      cs240/record-indexer/src/server/db/importer/Importer.java
  76. +21
    -0
      cs240/record-indexer/src/server/errors/ServerException.java
  77. +77
    -0
      cs240/record-indexer/src/server/handlers/DownloadBatchHandler.java
  78. +70
    -0
      cs240/record-indexer/src/server/handlers/GetFieldsHandler.java
  79. +58
    -0
      cs240/record-indexer/src/server/handlers/GetProjectsHandler.java
  80. +55
    -0
      cs240/record-indexer/src/server/handlers/GetSampleImageHandler.java
  81. +85
    -0
      cs240/record-indexer/src/server/handlers/SearchHandler.java
  82. +36
    -0
      cs240/record-indexer/src/server/handlers/StaticsHandler.java
  83. +75
    -0
      cs240/record-indexer/src/server/handlers/SubmitBatchHandler.java
  84. +46
    -0
      cs240/record-indexer/src/server/handlers/ValidateUserHandler.java
  85. +76
    -0
      cs240/record-indexer/src/server/handlers/common/BaseHanlder.java
  86. +5
    -0
      cs240/record-indexer/src/shared/common/BaseModel.java
  87. +22
    -0
      cs240/record-indexer/src/shared/communication/common/ARecord.java
  88. +71
    -0
      cs240/record-indexer/src/shared/communication/common/Fields.java
  89. +24
    -0
      cs240/record-indexer/src/shared/communication/common/Project_Res.java
  90. +56
    -0
      cs240/record-indexer/src/shared/communication/common/Tuple.java
  91. +55
    -0
      cs240/record-indexer/src/shared/communication/params/DownloadBatch_Param.java
  92. +50
    -0
      cs240/record-indexer/src/shared/communication/params/Fields_Param.java
  93. +41
    -0
      cs240/record-indexer/src/shared/communication/params/Projects_Param.java
  94. +51
    -0
      cs240/record-indexer/src/shared/communication/params/SampleImage_Param.java
  95. +63
    -0
      cs240/record-indexer/src/shared/communication/params/Search_Param.java
  96. +85
    -0
      cs240/record-indexer/src/shared/communication/params/SubmitBatch_Param.java
  97. +44
    -0
      cs240/record-indexer/src/shared/communication/params/ValidateUser_Param.java
  98. +131
    -0
      cs240/record-indexer/src/shared/communication/responses/DownloadBatch_Res.java
  99. +61
    -0
      cs240/record-indexer/src/shared/communication/responses/Fields_Res.java
  100. +0
    -0
      cs240/record-indexer/src/shared/communication/responses/Projects_Res.java

+ 2
- 0
cs240/record-indexer/.gitignore View File

@@ -0,0 +1,2 @@
build/
out/

+ 1
- 0
cs240/record-indexer/.idea/.name View File

@@ -0,0 +1 @@
6-record-indexer

+ 17
- 0
cs240/record-indexer/.idea/artifacts/search_gui_jar.xml View File

@@ -0,0 +1,17 @@
<component name="ArtifactManager">
<artifact type="jar" name="search_gui:jar">
<output-path>$PROJECT_DIR$/out/artifacts/search_gui_jar</output-path>
<root id="archive" name="6-record-indexer.jar">
<element id="module-output" name="6-record-indexer" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/commons-io-2.4/commons-io-2.4.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/commons-io-2.4/commons-io-2.4-tests.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/commons-io-2.4/commons-io-2.4-javadoc.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/commons-io-2.4/commons-io-2.4-sources.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/commons-io-2.4/commons-io-2.4-test-sources.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/sqlite-jdbc-3.8.0-20130827.035027-1.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/checkstyle-5.3-all.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/junit-4.8.2.jar" path-in-jar="/" />
<element id="extracted-dir" path="$PROJECT_DIR$/lib/xstream-1.4.2.jar" path-in-jar="/" />
</root>
</artifact>
</component>

+ 13
- 0
cs240/record-indexer/.idea/codeStyleSettings.xml View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectCodeStyleSettingsManager">
<option name="PER_PROJECT_SETTINGS">
<value>
<XML>
<option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
</XML>
</value>
</option>
</component>
</project>


+ 23
- 0
cs240/record-indexer/.idea/compiler.xml View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<option name="DEFAULT_COMPILER" value="Javac" />
<resourceExtensions />
<wildcardResourcePatterns>
<entry name="!?*.java" />
<entry name="!?*.form" />
<entry name="!?*.class" />
<entry name="!?*.groovy" />
<entry name="!?*.scala" />
<entry name="!?*.flex" />
<entry name="!?*.kt" />
<entry name="!?*.clj" />
</wildcardResourcePatterns>
<annotationProcessing>
<profile default="true" name="Default" enabled="false">
<processorPath useClasspath="true" />
</profile>
</annotationProcessing>
</component>
</project>


+ 5
- 0
cs240/record-indexer/.idea/copyright/profiles_settings.xml View File

@@ -0,0 +1,5 @@
<component name="CopyrightManager">
<settings default="">
<module2copyright />
</settings>
</component>

+ 11
- 0
cs240/record-indexer/.idea/dictionaries/film42.xml View File

@@ -0,0 +1,11 @@
<component name="ProjectDictionaryState">
<dictionary name="film42">
<words>
<w>accessors</w>
<w>congratz</w>
<w>hackery</w>
<w>thornburg</w>
<w>tuples</w>
</words>
</dictionary>
</component>

+ 5
- 0
cs240/record-indexer/.idea/encodings.xml View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
</project>


+ 11
- 0
cs240/record-indexer/.idea/libraries/checkstyle_5_3_all.xml View File

@@ -0,0 +1,11 @@
<component name="libraryTable">
<library name="checkstyle-5.3-all">
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/checkstyle-5.3-all.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/junit-4.8.2.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/xstream-1.4.2.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

+ 15
- 0
cs240/record-indexer/.idea/libraries/commons_io_2.xml View File

@@ -0,0 +1,15 @@
<component name="libraryTable">
<library name="commons-io-2">
<CLASSES>
<root url="file://$PROJECT_DIR$/lib/commons-io-2.4" />
</CLASSES>
<JAVADOC>
<root url="file://$PROJECT_DIR$/lib/commons-io-2.4/docs" />
</JAVADOC>
<SOURCES>
<root url="file://$PROJECT_DIR$/lib/commons-io-2.4" />
</SOURCES>
<jarDirectory url="file://$PROJECT_DIR$/lib/commons-io-2.4" recursive="false" />
<jarDirectory url="file://$PROJECT_DIR$/lib/commons-io-2.4" recursive="false" type="SOURCES" />
</library>
</component>

+ 11
- 0
cs240/record-indexer/.idea/libraries/sqlite_jdbc_3_8_0_20130827_035027_1.xml View File

@@ -0,0 +1,11 @@
<component name="libraryTable">
<library name="sqlite-jdbc-3.8.0-20130827.035027-1">
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/sqlite-jdbc-3.8.0-20130827.035027-1.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/lib/sqlite-jdbc-3.8.0-20130827.035027-1.jar!/" />
</SOURCES>
</library>
</component>

+ 28
- 0
cs240/record-indexer/.idea/misc.xml View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="EntryPointsManager">
<entry_points version="2.0" />
</component>
<component name="JavadocGenerationManager">
<option name="OUTPUT_DIRECTORY" value="$PROJECT_DIR$/../5-design-document/docs" />
<option name="OPTION_SCOPE" value="package" />
<option name="OPTION_HIERARCHY" value="true" />
<option name="OPTION_NAVIGATOR" value="true" />
<option name="OPTION_INDEX" value="true" />
<option name="OPTION_SEPARATE_INDEX" value="true" />
<option name="OPTION_DOCUMENT_TAG_USE" value="false" />
<option name="OPTION_DOCUMENT_TAG_AUTHOR" value="false" />
<option name="OPTION_DOCUMENT_TAG_VERSION" value="false" />
<option name="OPTION_DOCUMENT_TAG_DEPRECATED" value="true" />
<option name="OPTION_DEPRECATED_LIST" value="true" />
<option name="OTHER_OPTIONS" />
<option name="HEAP_SIZE" />
<option name="LOCALE" />
<option name="OPEN_IN_BROWSER" value="true" />
<option name="OPTION_INCLUDE_LIBS" value="false" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" assert-keyword="true" jdk-15="true" project-jdk-name="1.7" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>


+ 9
- 0
cs240/record-indexer/.idea/modules.xml View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/6-record-indexer.iml" filepath="$PROJECT_DIR$/6-record-indexer.iml" />
</modules>
</component>
</project>


+ 5
- 0
cs240/record-indexer/.idea/scopes/scope_settings.xml View File

@@ -0,0 +1,5 @@
<component name="DependencyValidationManager">
<state>
<option name="SKIP_IMPORT_STATEMENTS" value="false" />
</state>
</component>

+ 125
- 0
cs240/record-indexer/.idea/uiDesigner.xml View File

@@ -0,0 +1,125 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>


+ 7
- 0
cs240/record-indexer/.idea/vcs.xml View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="" />
</component>
</project>


+ 1427
- 0
cs240/record-indexer/.idea/workspace.xml
File diff suppressed because it is too large
View File


+ 200
- 0
cs240/record-indexer/build.xml View File

@@ -0,0 +1,200 @@
<project name="Record Indexer" default="compile" basedir=".">
<!-- PROPERTIES -->
<!-- ********** -->
<!-- Directory containing application source code -->
<property name="src" location="src"/>
<!-- Directory containing testing source code -->
<property name="test" location="test"/>
<!-- Directory containing Java libraries -->
<property name="lib" location="lib"/>
<!-- Directory where the Java compiler puts .class files -->
<property name="build" location="build"/>
<!-- Directory containing database files -->
<property name="database" location="db"/>
<!-- Directory containing demo files -->
<property name="demo" location="demo"/>
<!-- Directory containing passoff files -->
<property name="passoff" location="passoff"/>
<!-- Database file used by the server -->
<property name="db-file" location="${database}/database.sqlite3"/>
<!-- Database file containing empty tables. -->
<property name="empty-db-file" location="${database}/template.sqlite3"/>
<!-- File containing the report output by Checkstyle -->
<property name="checkstyle-report-file" location="checkstyle-report.txt"/>
<!-- Default values for command-line properties. Values specified on the command-line will override these. -->
<property name="file" value="demo/indexer_data/Records/Records.xml"/>
<property name="host" value="localhost"/>
<property name="port" value="39640"/>
<!-- CLASS PATHS -->
<!-- *********** -->
<path id="lib-classpath">
<fileset dir="${lib}">
<include name="**/*.jar" />
</fileset>
</path>
<path id="all-classpath">
<path refid="lib-classpath"/>
<pathelement location="${build}"/>
</path>
<path id="passoff-classpath">
<path refid="all-classpath"/>
<pathelement location="${passoff}/server-passoff.jar"/>
</path>
<!-- TASK DEFINITIONS -->
<!-- **************** -->
<taskdef classpathref="lib-classpath" resource="checkstyletask.properties"/>
<!-- TARGETS -->
<!-- ******* -->
<target name="init" description="create build directories">
<tstamp/>
<mkdir dir="${build}"/>
<mkdir dir="${passoff}"/>
</target>
<target name="clean" description="delete build files and directories">
<delete dir="${build}"/>
<delete dir="${passoff}"/>
</target>
<target name="compile" depends="init" description="compile the source code">
<javac srcdir="${src}" classpathref="lib-classpath" destdir="${build}" debug="true" includeantruntime="true" />
<javac srcdir="${test}" classpathref="lib-classpath" destdir="${build}" debug="true" includeantruntime="true" />
</target>
<!-- ant importer -Dfile=<INDEXER_DATA_XML_FILE> -->
<!-- EXAMPLE: ant importer -Dfile=dir1/dir2/indexer_data.xml -->
<target name="import" depends="compile" description="import indexer data">
<copy file="${empty-db-file}" tofile="${db-file}" overwrite="true"/>
<java classname="server.db.importer.Importer" fork="yes">
<classpath>
<path refid="all-classpath"/>
</classpath>
<arg value="${file}"/>
<assertions>
<enable/>
</assertions>
</java>
</target>
<!-- ant server {-Dport=<SERVER_PORT_NUMBER>} -->
<!-- EXAMPLE: ant server -Dport=39640 -->
<!-- If port number is omitted, run on default port. -->
<!-- EXAMPLE: ant server -->
<target name="server" depends="compile" description="run server on specified port">
<java classname="server.Server" fork="yes">
<classpath>
<path refid="all-classpath"/>
</classpath>
<arg value="${port}"/>
<assertions>
<enable/>
</assertions>
</java>
</target>
<target name="server-gui" depends="compile" description="run the server test gui">
<java classname="servertester.GuiTester" fork="yes">
<classpath>
<path refid="all-classpath"/>
</classpath>
<assertions>
<enable/>
</assertions>
</java>
</target>
<target name="server-tests" depends="compile" description="run automated server tests">
<java classname="server.ServerUnitTests" fork="yes">
<classpath>
<path refid="all-classpath"/>
</classpath>
<assertions>
<enable/>
</assertions>
</java>
</target>
<!-- ant server-passoff {-Dhost=<SERVER_HOST>} {-Dport=<SERVER_PORT_NUMBER>} -->
<!-- EXAMPLE: ant server-passoff -Dhost=testserver.cs.byu.edu -Dport=39640 -->
<!-- If host and/or port number are omitted, default values are used. -->
<!-- EXAMPLE: ant server-passoff -->
<target name="server-passoff" depends="compile" description="run server passoff using server on specified host and port">
<java classname="passoff.ServerPassoff" fork="yes">
<classpath>
<path refid="passoff-classpath"/>
</classpath>
<arg value="${host}"/>
<arg value="${port}"/>
<assertions>
<enable/>
</assertions>
</java>
</target>
<!-- ant client {-Dhost=<SERVER_HOST>} {-Dport=<SERVER_PORT_NUMBER>} -->
<!-- EXAMPLE: ant client -Dhost=testserver.cs.byu.edu -Dport=39640 -->
<!-- If host and/or port number are omitted, default values are used. -->
<!-- EXAMPLE: ant client -->
<target name="client" depends="compile" description="run client using server on specified host and port">
<java classname="client.Client" fork="yes">
<classpath>
<path refid="all-classpath"/>
</classpath>
<arg value="${host}"/>
<arg value="${port}"/>
<assertions>
<enable/>
</assertions>
</java>
</target>
<target name="client-tests" depends="compile" description="run automated client tests">
<java classname="client.ClientUnitTests" fork="yes">
<classpath>
<path refid="all-classpath"/>
</classpath>
<assertions>
<enable/>
</assertions>
</java>
</target>
<target name="checkstyle" depends="compile" description="run checkstyle on all source code">
<checkstyle config="checkstyle.xml">
<fileset dir="${src}" includes="**/*.java">
</fileset>
<formatter type="plain" toFile="${checkstyle-report-file}"/>
<classpath>
<pathelement location="${build}"/>
</classpath>
</checkstyle>
</target>
<target name="demo" description="run the demo">
<java jar="${demo}/record-indexer-demo.jar" fork="yes" dir="${demo}">
</java>
</target>
</project>

+ 58
- 0
cs240/record-indexer/checkstyle.xml View File

@@ -0,0 +1,58 @@
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
<module name="Checker">
<module name="FileLength">
<property name="max" value="2000"/>
</module>
<module name="TreeWalker">
<property name="tabWidth" value="4"/>
<module name="NestedForDepth">
<property name="max" value="1"/>
</module>
<module name="NestedIfDepth">
<property name="max" value="2"/>
</module>
<module name="NestedTryDepth">
<property name="max" value="1"/>
</module>
<module name="BooleanExpressionComplexity">
<property name="max" value="5"/>
</module>
<module name="CyclomaticComplexity">
<property name="max" value="10"/>
</module>
<module name="NPathComplexity">
<property name="max" value="200"/>
</module>
<module name="LineLength">
<property name="max" value="100"/>
</module>
<module name="MethodLength">
<property name="max" value="120"/>
<property name="countEmpty" value="false"/>
</module>
<module name="ParameterNumber">
<property name="max" value="7"/>
<property name="tokens" value="METHOD_DEF"/>
</module>
</module>
</module>

+ 107
- 0
cs240/record-indexer/src/client/Client.java View File

@@ -0,0 +1,107 @@
package client;

import client.communication.Communicator;
import client.components.MainWindow;
import client.components.loginWindow.ErrorLoginDialog;
import client.components.loginWindow.LoginWindow;
import client.components.loginWindow.SuccessLoginDialog;
import shared.communication.params.ValidateUser_Param;
import shared.communication.responses.ValidateUser_Res;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class Client {

private LoginWindow loginWindow;
private Communicator communicator;

public Client(Communicator communicator) {
this.communicator = communicator;
}

public void run() {
loginWindow = new LoginWindow(communicator);
loginWindow.addLoginListener(loginListener);

// Run
EventQueue.invokeLater(new Runnable() {
public void run() {
loginWindow.setVisible(true);

}
});
}

public static void main(String[] args) {
// Create Window
String host = args[0];
String port = args[1];
String server = "http://"+host+":"+port+"/";
Communicator communicator = new Communicator(server);

Client client = new Client(communicator);
client.run();
}

private ActionListener loginListener = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
ValidateUser_Param param = new ValidateUser_Param();
param.setUsername(loginWindow.getUsername());
param.setPassword(loginWindow.getPassword());

try {
ValidateUser_Res validateUserRes;
validateUserRes = communicator.validateUser(param);

loginWindow.setVisible(false);

SuccessLoginDialog successLoginDialog = new SuccessLoginDialog(validateUserRes);
successLoginDialog.addWindowListener(openMainWindowListener);
successLoginDialog.setVisible(true);


} catch (Exception execption) {
ErrorLoginDialog errorLoginDialog = new ErrorLoginDialog();
errorLoginDialog.setVisible(true);
}
}
};

private WindowListener openMainWindowListener = new WindowAdapter() {
@Override
public void windowClosed(WindowEvent e) {
super.windowClosed(e);

// Run
EventQueue.invokeLater(new Runnable() {
public void run() {
MainWindow frame = new MainWindow(communicator, loginWindow.getUsername(),
loginWindow.getPassword());
frame.addWindowListener(logoutListener);
frame.setVisible(true);
}
});
}
};

private WindowListener logoutListener = new WindowAdapter() {
@Override
public void windowClosed(WindowEvent e) {
super.windowClosed(e);

loginWindow = new LoginWindow(communicator);
loginWindow.addLoginListener(loginListener);

// Run
EventQueue.invokeLater(new Runnable() {
public void run() {
loginWindow.setVisible(true);
}
});
}
};

}

+ 119
- 0
cs240/record-indexer/src/client/communication/Communicator.java View File

@@ -0,0 +1,119 @@
package client.communication;

import client.communication.errors.RemoteServerErrorException;
import client.communication.errors.UnauthorizedAccessException;
import client.communication.modules.HttpClient;
import shared.communication.params.*;
import shared.communication.responses.*;

import java.io.ByteArrayOutputStream;

public class Communicator {

public Communicator(String serverPath) {
this.serverPath = serverPath;
}

private String serverPath;

public String getServerPath() {
return serverPath;
}

public ValidateUser_Res validateUser(ValidateUser_Param user)
throws UnauthorizedAccessException, RemoteServerErrorException {

String resource = "validateUser/";
String response = HttpClient.post(serverPath + resource, user.toXML());

if(response == null)
return null;

return ValidateUser_Res.serialize(response);
}

public Projects_Res getProjects(Projects_Param projects)
throws UnauthorizedAccessException, RemoteServerErrorException {

String resource = "getProjects/";
String response = HttpClient.post(serverPath + resource, projects.toXML());

if(response == null)
return null;

return Projects_Res.serialize(response);
}

public SampleImage_Res getSampleImage(SampleImage_Param sampleImage)
throws UnauthorizedAccessException, RemoteServerErrorException {

String resource = "getSampleImage/";
String response = HttpClient.post(serverPath + resource, sampleImage.toXML());

if(response == null)
return null;

return SampleImage_Res.serialize(response);
}

public DownloadBatch_Res downloadBatch(DownloadBatch_Param downloadBatch)
throws UnauthorizedAccessException, RemoteServerErrorException {

String resource = "downloadBatch/";
String response = HttpClient.post(serverPath + resource, downloadBatch.toXML());

if(response == null)
return null;

return DownloadBatch_Res.serialize(response);
}

public SubmitBatch_Res submitBatch(SubmitBatch_Param submitBatch)
throws UnauthorizedAccessException, RemoteServerErrorException {

String resource = "submitBatch/";
String response = HttpClient.post(serverPath + resource, submitBatch.toXML());

if(response == null)
return null;

return SubmitBatch_Res.serialize(response);
}

public Fields_Res getFields(Fields_Param fields)
throws UnauthorizedAccessException, RemoteServerErrorException {

String resource = "getFields/";
String response = HttpClient.post(serverPath + resource, fields.toXML());

if(response == null)
return null;

return Fields_Res.serialize(response);
}

public Search_Res search(Search_Param search)
throws UnauthorizedAccessException, RemoteServerErrorException {

String resource = "search/";
String response = HttpClient.post(serverPath + resource, search.toXML());

if(response == null)
return null;

return Search_Res.serialize(response);
}

public ByteArrayOutputStream downloadStatic(String resource) {

try {
return HttpClient.getStatic(serverPath+resource);
} catch (UnauthorizedAccessException e) {
return null;
} catch (RemoteServerErrorException e) {
return null;
}

}

}

+ 20
- 0
cs240/record-indexer/src/client/communication/errors/RemoteServerErrorException.java View File

@@ -0,0 +1,20 @@
package client.communication.errors;

public class RemoteServerErrorException extends Exception {

public RemoteServerErrorException() {
}

public RemoteServerErrorException(String message) {
super(message);
}

public RemoteServerErrorException(Throwable throwable) {
super(throwable);
}

public RemoteServerErrorException(String message, Throwable throwable) {
super(message, throwable);
}

}

+ 21
- 0
cs240/record-indexer/src/client/communication/errors/UnauthorizedAccessException.java View File

@@ -0,0 +1,21 @@
package client.communication.errors;

@SuppressWarnings("serial")
public class UnauthorizedAccessException extends Exception {

public UnauthorizedAccessException() {
}

public UnauthorizedAccessException(String message) {
super(message);
}

public UnauthorizedAccessException(Throwable throwable) {
super(throwable);
}

public UnauthorizedAccessException(String message, Throwable throwable) {
super(message, throwable);
}

}

+ 113
- 0
cs240/record-indexer/src/client/communication/modules/HttpClient.java View File

@@ -0,0 +1,113 @@
package client.communication.modules;

import client.communication.errors.RemoteServerErrorException;
import client.communication.errors.UnauthorizedAccessException;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

public class HttpClient {

private static InputStream request(String url, String method, String request)
throws RemoteServerErrorException, UnauthorizedAccessException{

try {
URL requestURL = new URL(url);
HttpURLConnection connection = (HttpURLConnection) requestURL.openConnection();

// We can generalize, whatever
connection.setDoOutput(true);

connection.setRequestMethod(method);

OutputStreamWriter outputStreamWriter = new OutputStreamWriter(
connection.getOutputStream());
outputStreamWriter.write(request);
outputStreamWriter.close();

switch (connection.getResponseCode()) {
case HttpURLConnection.HTTP_OK:
return connection.getInputStream();
case HttpURLConnection.HTTP_UNAUTHORIZED:
throw new UnauthorizedAccessException();
default:
throw new RemoteServerErrorException();
}

} catch (MalformedURLException e) {
throw new RemoteServerErrorException();
} catch (IOException e) {
throw new RemoteServerErrorException();
}
}

public static String get(String url)
throws UnauthorizedAccessException, RemoteServerErrorException {

InputStream response = request(url, "GET", "");
return inputStreamToString(response);
}

public static String post(String url, String req)
throws UnauthorizedAccessException, RemoteServerErrorException {

InputStream response = request(url, "POST", req);
return inputStreamToString(response);
}

public static ByteArrayOutputStream getStatic(String url)
throws UnauthorizedAccessException, RemoteServerErrorException {

InputStream response = request(url, "GET", "");

if(response != null) {
try {

ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();


byte[] byteArray = new byte[512];

int bytesRead = 0;
while((bytesRead = response.read(byteArray)) != -1) {
byteArrayOutputStream.write(byteArray, 0, bytesRead);
}

return byteArrayOutputStream;


} catch (IOException e) {
return null;
}
}
return null;
}

private static String inputStreamToString(InputStream inputStream) {
StringBuilder stringBuilder = new StringBuilder();
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(inputStream));

String line;
try {
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try { bufferedReader.close(); } catch (IOException e) {
e.printStackTrace(); }
}

try {
inputStream.close();
} catch (IOException e) {

}
return stringBuilder.toString();
}

}

+ 102
- 0
cs240/record-indexer/src/client/components/FileMenu.java View File

@@ -0,0 +1,102 @@
package client.components;

import client.communication.Communicator;
import client.components.downloadModal.DownloadModal;
import client.components.loginWindow.ErrorLoginDialog;
import client.persistence.ImageState;
import client.persistence.NewProjectListener;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;

public class FileMenu extends JMenuBar {
private MainWindow mainWindow;
private Communicator communicator;
private ImageState imageState;
private JMenuItem eMenuItem1;

public FileMenu(MainWindow mainWindow, Communicator communicator, ImageState imageState) {
this.mainWindow = mainWindow;
this.communicator = communicator;
this.imageState = imageState;

this.imageState.addNewProjectListener(newProjectListener);

setupView();
}

private void setupView() {
// Prevents menu items from filling the whole length
this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS));

JMenu file1 = new JMenu("File");

eMenuItem1 = new JMenuItem("Download Batch");
eMenuItem1.addActionListener(downloadBatchAction);
eMenuItem1.setEnabled(!imageState.isHasImage());
eMenuItem1.setToolTipText("Exit application");

JMenuItem eMenuItem2 = new JMenuItem("Logout");
eMenuItem2.addActionListener(logoutAction);
eMenuItem2.setToolTipText("Exit application");

JMenuItem eMenuItem3 = new JMenuItem("Exit");
eMenuItem3.addActionListener(exitAction);
eMenuItem2.setToolTipText("Exit application");

file1.add(eMenuItem1);
file1.add(eMenuItem2);
file1.add(eMenuItem3);

// Add to self
this.add(file1);
this.setBackground(Color.WHITE);
}

private void updateSettings() {
imageState.getSettings().setWindowHeight(mainWindow.getHeight());
imageState.getSettings().setWindowWidth(mainWindow.getWidth());

Point point = mainWindow.getLocationOnScreen();
imageState.getSettings().setWindowPositionX((int) point.getX());
imageState.getSettings().setWindowPositionY((int) point.getY());
imageState.save();
}


private ActionListener downloadBatchAction = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
DownloadModal downloadModal = new DownloadModal(imageState, communicator);
downloadModal.setVisible(true);
}
};

private ActionListener logoutAction = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
updateSettings();
mainWindow.dispose();
}
};

private ActionListener exitAction = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
updateSettings();
System.exit(1);
}
};

private NewProjectListener newProjectListener = new NewProjectListener() {
@Override
public void hasNewProject() {
boolean status = imageState.isHasImage();
eMenuItem1.setEnabled(!status);
}
};

}

+ 147
- 0
cs240/record-indexer/src/client/components/MainWindow.java View File

@@ -0,0 +1,147 @@
package client.components;

import client.communication.Communicator;
import client.components.downloadModal.DownloadModal;
import client.components.imagePanel.ImagePanel;
import client.persistence.Cell;
import client.persistence.ImageState;
import client.persistence.NewProjectListener;
import client.persistence.Settings;

import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.*;

public class MainWindow extends JFrame implements Serializable {

public ImageState imageState;
private Communicator communicator;

JSplitPane body = new JSplitPane(JSplitPane.VERTICAL_SPLIT, new JPanel(), new JPanel());

public MainWindow(Communicator communicator, String username, String password) {
Settings settings = loadSettings(username);

this.imageState = loadImageState(username);

if(this.imageState == null) {
this.imageState = new ImageState(settings, communicator, username, password);
} else {
this.imageState.setCommunicator(communicator);
}

this.imageState.setSettings(settings);

this.imageState.addNewProjectListener(newProjectListener);
this.communicator = communicator;

this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

this.setSize(settings.getWindowWidth(), settings.getWindowHeight());
this.setLocation(settings.getWindowPositionX(), settings.getWindowPositionY());

setupView();

this.imageState.initEvents();
this.addWindowListener(windowListener);
}

private void setupView() {
setupFileMenu();
setupImagePanel();
setupSplitView();

this.add(body, BorderLayout.CENTER);

body.addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY, new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent pce) {
int dividerLocation = body.getDividerLocation();

imageState.getSettings().setBaseSplitY(dividerLocation);
}
});
}

private void setupFileMenu() {
// Setup File Menu
this.add(new FileMenu(this, communicator, imageState), BorderLayout.NORTH);
}

private void setupImagePanel() {
body.setTopComponent(new ImagePanel(imageState));
}

private void setupSplitView() {
SplitBase splitBase = new SplitBase(imageState, communicator);

body.setBottomComponent(splitBase);
body.setBorder(null);
body.setDividerLocation(imageState.getSettings().getBaseSplitY());
}

public ImageState loadImageState(String username) {
File dest = new File("profiles/"+username);
if(dest.exists()) {
FileInputStream fis = null;
ObjectInputStream in = null;
try {
fis = new FileInputStream("profiles/"+username+"/state.ser");
in = new ObjectInputStream(fis);
return (ImageState)in.readObject();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}

return null;
}

public Settings loadSettings(String username) {
File dest = new File("profiles/"+username);
if(dest.exists()) {
FileInputStream fis = null;
ObjectInputStream in = null;
try {
fis = new FileInputStream("profiles/"+username+"/settings.ser");
in = new ObjectInputStream(fis);
return (Settings)in.readObject();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}

return Settings.defaultSettings();
}

private WindowListener windowListener = new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
super.windowClosing(e);

}

@Override
public void windowClosed(WindowEvent e) {
super.windowClosed(e);

}
};

private NewProjectListener newProjectListener = new NewProjectListener() {
@Override
public void hasNewProject() {


}
};
}

+ 74
- 0
cs240/record-indexer/src/client/components/SplitBase.java View File

@@ -0,0 +1,74 @@
package client.components;

import client.communication.Communicator;
import client.components.fieldHelp.FieldHelp;
import client.components.formEntry.FormEntry;
import client.persistence.SyncContext;
import client.components.tableEntry.TableEntry;
import client.persistence.Cell;
import client.persistence.ImageState;

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

public class SplitBase extends JSplitPane {

private ImageState imageState;
private JTabbedPane tabbedPane;
private TableEntry tableEntry;
private FormEntry formEntry;
private Communicator communicator;

public SplitBase(ImageState imageState, Communicator communicator) {
this.imageState = imageState;
this.communicator = communicator;

setupView();

}

private void setupView() {
tabbedPane = new JTabbedPane();
tabbedPane.addChangeListener(changeListener);

tableEntry = new TableEntry(imageState);
tabbedPane.addTab("Table Entry", tableEntry);

formEntry = new FormEntry(imageState);
tabbedPane.addTab("Form Entry", formEntry);

this.setLeftComponent(tabbedPane);

JTabbedPane tabbedPane2 = new JTabbedPane();
tabbedPane2.addTab("Field Help", new FieldHelp(imageState, communicator));
tabbedPane2.addTab("Image Navigator", new JPanel());

this.setRightComponent(tabbedPane2);

this.addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY, new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent pce) {
int dividerLocation = getDividerLocation();

imageState.getSettings().setBaseSplitX(dividerLocation);
}
});


this.setDividerLocation(imageState.getSettings().getBaseSplitX());

}

private ChangeListener changeListener = new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
if(tabbedPane.getSelectedIndex() == 1) {
formEntry.becameVisible();
}
}
};

}

+ 156
- 0
cs240/record-indexer/src/client/components/downloadModal/DownloadModal.java View File

@@ -0,0 +1,156 @@
package client.components.downloadModal;

import client.communication.Communicator;
import client.communication.errors.RemoteServerErrorException;
import client.communication.errors.UnauthorizedAccessException;
import client.persistence.ImageState;
import shared.communication.common.Project_Res;
import shared.communication.params.Projects_Param;
import shared.communication.params.SampleImage_Param;
import shared.communication.responses.Projects_Res;
import shared.communication.responses.SampleImage_Res;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.*;
import java.util.List;

public class DownloadModal extends JDialog {

private ImageState imageState;
private Communicator communicator;
private List<Project_Res> projects;
private JComboBox batchSelect;


public DownloadModal(ImageState imageState, Communicator communicator) {
this.imageState = imageState;
this.communicator = communicator;

setupView();
}

private void setupView() {
this.setModalityType(Dialog.ModalityType.DOCUMENT_MODAL);
this.setTitle("Download Image");
this.setSize(350, 100);
this.setResizable(false);
this.setLocationRelativeTo(null);
this.setLayout(new FlowLayout());

JLabel label = new JLabel("Project: ");
this.add(label);

projects = getProjects().getProjectsList();

List<String> values = getProjectNames();

batchSelect = new JComboBox(values.toArray());
this.add(batchSelect);

JButton sampleImageButton = new JButton("Sample Image?");
sampleImageButton.addActionListener(getSampleImageListener);
this.add(sampleImageButton);

JButton cancelButton = new JButton("Cancel");
cancelButton.addActionListener(closeListener);
this.add(cancelButton);

JButton downloadButton = new JButton("Download");
downloadButton.addActionListener(downloadListener);
this.add(downloadButton);
}

private Projects_Res getProjects() {
Projects_Param param = new Projects_Param();
param.setUsername(imageState.getUsername());
param.setPassword(imageState.getPassword());

try {
return communicator.getProjects(param);
} catch (Exception e) {
e.printStackTrace();
}

return null;
}

private SampleImage_Res getSampleImage(int projectId) {
SampleImage_Param param = new SampleImage_Param();
param.setUsername(imageState.getUsername());
param.setPassword(imageState.getPassword());
param.setProjectId(projectId);

try {
return communicator.getSampleImage(param);
} catch (Exception e) {

}
return null;
}

private ActionListener getSampleImageListener = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
String projectTitle = (String)batchSelect.getSelectedItem();
int projectId = getProjectIdForName(projectTitle);
SampleImage_Res res = getSampleImage(projectId);

String fullPath = communicator.getServerPath() + res.getUrl();

SampleImageModal sampleImageModal = new SampleImageModal(fullPath);
sampleImageModal.setVisible(true);

}
};

private ActionListener closeListener = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
setVisible(false);
dispatchEvent(new WindowEvent(DownloadModal.this, WindowEvent.WINDOW_CLOSING));
}
};

private ActionListener downloadListener = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
String projectTitle = (String)batchSelect.getSelectedItem();
int projectId = getProjectIdForName(projectTitle);

imageState.downloadProject(projectId);

setVisible(false);
dispatchEvent(new WindowEvent(DownloadModal.this, WindowEvent.WINDOW_CLOSING));
}
};

private int getProjectIdForName(String title) {

for(Project_Res project : projects) {

if(title.equals(project.getTitle())) {
return project.getId();
}
}

return -1;
}

private List<String> getProjectNames() {
ArrayList<String> titles = new ArrayList<>();

for(Project_Res project : projects) {
titles.add(project.getTitle());
}

return titles;
}
}

+ 25
- 0
cs240/record-indexer/src/client/components/downloadModal/SampleImage.java View File

@@ -0,0 +1,25 @@
package client.components.downloadModal;

import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;


public class SampleImage extends JPanel {

BufferedImage image;

public SampleImage(BufferedImage image) {
this.image = image;
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;

g2.scale(0.7, 0.7);
g2.drawImage(image, 0, 0, null);
}

}

+ 52
- 0
cs240/record-indexer/src/client/components/downloadModal/SampleImageModal.java View File

@@ -0,0 +1,52 @@
package client.components.downloadModal;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;

public class SampleImageModal extends JDialog {

BufferedImage image;

public SampleImageModal(String path) {
try {
image = ImageIO.read(new URL(path));
} catch (Exception e1) {
return;
}

setupView();
}

private void setupView() {
this.setTitle("Sample Image from XXXXXXX");
this.setModalityType(Dialog.ModalityType.DOCUMENT_MODAL);
this.setSize(500, 410);
this.setResizable(false);
this.setLocationRelativeTo(null);

SampleImage sampleImage = new SampleImage(image);

this.add(sampleImage, BorderLayout.CENTER);

JButton closeButton = new JButton("Close");
closeButton.addActionListener(closeListener);
this.add(closeButton, BorderLayout.SOUTH);

}

private ActionListener closeListener = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
setVisible(false);
dispatchEvent(new WindowEvent(SampleImageModal.this, WindowEvent.WINDOW_CLOSING));
}
};
}

+ 77
- 0
cs240/record-indexer/src/client/components/fieldHelp/FieldHelp.java View File

@@ -0,0 +1,77 @@
package client.components.fieldHelp;

import client.communication.Communicator;
import client.persistence.Cell;
import client.persistence.ImageState;
import client.persistence.ImageStateListener;
import client.persistence.NewProjectListener;
import shared.communication.common.Fields;

import javax.swing.*;
import java.awt.*;
import java.io.IOException;

public class FieldHelp extends JPanel {

private ImageState imageState;

private String[] columns;
private int currentColumn;
private JEditorPane editorPane;
private Communicator communicator;

public FieldHelp(ImageState imageState, Communicator communicator) {
this.imageState = imageState;
this.communicator = communicator;

this.currentColumn = 0;
this.columns = imageState.getColumnNames();

setupView();

this.imageState.addListener(imageStateListener);
this.imageState.addNewProjectListener(newProjectListener);
}

private void setupView() {
editorPane = new JEditorPane();
editorPane.setContentType("text/html");
editorPane.setEditable(false);

this.setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
this.add(new JScrollPane(editorPane), BorderLayout.CENTER);
}

private void updateView() {
if(!imageState.isHasImage()) return;

Fields field = imageState.getFieldsMetaData().get(currentColumn);
String path = communicator.getServerPath() + field.getHelpUrl();

try {
editorPane.setPage(path);
} catch (IOException e) {
e.printStackTrace();
}
}

private ImageStateListener imageStateListener = new ImageStateListener() {
@Override
public void valueChanged(Cell cell, String newValue) {

}

@Override
public void selectedCellChanged(Cell newSelectedCell) {
currentColumn = newSelectedCell.getField();
updateView();
}
};

private NewProjectListener newProjectListener = new NewProjectListener() {
@Override
public void hasNewProject() {
editorPane.setText("");
}
};
}

+ 141
- 0
cs240/record-indexer/src/client/components/formEntry/FormEntry.java View File

@@ -0,0 +1,141 @@
package client.components.formEntry;

import client.modules.spellChecker.KnownData;
import client.persistence.*;

import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.*;
import java.awt.event.*;

public class FormEntry extends JPanel {

private JList rowNumberList;
private FormTable formTable;
private JSplitPane splitPane;

private Cell currentCell;
private String[][] model;
private String[] columnNames;
private Integer[] rowIds;

private ImageState imageState;

public FormEntry(ImageState imageState) {
this.imageState = imageState;

this.model = this.imageState.getModel();
this.columnNames = this.imageState.getColumnNames();

this.imageState.addNewProjectListener(newProjectListener);

setupView();
}

private void setupView() {
this.setLayout(new GridLayout(1,1));

this.rowIds = new Integer[model.length];
generateListData();

splitPane = new JSplitPane();
splitPane.setDividerLocation(50);
splitPane.setBorder(null);

formTable = new FormTable(imageState);

splitPane.setRightComponent(new JScrollPane(formTable));

rowNumberList = new JList(rowIds);
rowNumberList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
rowNumberList.setLayoutOrientation(JList.VERTICAL);
rowNumberList.setVisibleRowCount(-1);
rowNumberList.addListSelectionListener(listSelectionListener);
splitPane.setLeftComponent(new JScrollPane(rowNumberList));


this.add(splitPane);

imageState.addListener(imageStateListener);

}

public void generateListData() {
for(int i = 0; i < rowIds.length; i ++) {
rowIds[i] = (i+1);
}
}

@Override
public Dimension getMinimumSize() {
Dimension dim = super.getMinimumSize();
dim.width = 350;
return dim;
}

private ImageStateListener imageStateListener = new ImageStateListener() {
@Override
public void valueChanged(Cell cell, String newValue) {
int row = cell.getRecord();
int column = cell.getField();

rowNumberList.setSelectedIndex(row);
formTable.setValue(newValue, row, column);

splitPane.repaint();
}

@Override
public void selectedCellChanged(Cell newSelectedCell) {
int row = newSelectedCell.getRecord();
int column = newSelectedCell.getField();

currentCell = newSelectedCell;

rowNumberList.setSelectedIndex(row);
formTable.setCurrentCell(row, column);

splitPane.repaint();
}
};

private NewProjectListener newProjectListener = new NewProjectListener() {
@Override
public void hasNewProject() {
model = imageState.getModel();
columnNames = imageState.getColumnNames();

formTable.setDeactivated(true);
formTable = new FormTable(imageState);
splitPane.setRightComponent(new JScrollPane(formTable));

rowIds = new Integer[model.length];
generateListData();
rowNumberList.setListData(rowIds);
}
};

private ListSelectionListener listSelectionListener = new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
if(!getParent().getParent().getParent().isVisible()) return;

int newRow = rowNumberList.getSelectedIndex();

Cell cell = new Cell();
cell.setRecord(newRow);
cell.setField(currentCell.getField());

imageState.setSelectedCell(cell);
repaint();

}
};

public void becameVisible() {
formTable.setCurrentCellForce();
}


}

+ 195
- 0
cs240/record-indexer/src/client/components/formEntry/FormTable.java View File

@@ -0,0 +1,195 @@
package client.components.formEntry;

import client.modules.spellChecker.KnownData;
import client.persistence.Cell;
import client.persistence.ImageState;

import javax.swing.*;
import java.awt.*;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;

public class FormTable extends JPanel {

private String[] fieldNames;
private String[][] values;

private boolean updatingCell;

private ImageState imageState;

private int currentRow;
private boolean deactivated = false;

public FormTable(ImageState imageState) {

this.imageState = imageState;

this.fieldNames = this.imageState.getColumnNames();
this.values = this.imageState.getModel();

this.currentRow = 0;

setupView();
}

private void setupView() {
this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));

currentRow = 0;

initForm();

}

private void initForm() {
for(int i = 0; i < fieldNames.length; i++) {
String labelString = fieldNames[i];
String textFieldString = values[currentRow][i];

JPanel formContainer = new JPanel();

JLabel label = new JLabel(labelString);
label.setPreferredSize(new Dimension(100,30));
formContainer.add(label, BorderLayout.WEST);

JTextField textField = new JTextField(textFieldString);
textField.addFocusListener(generateFocusListener(textField, i));
textField.setPreferredSize(new Dimension(150, 30));

if(hasSuggestion(textField.getText(), i)) {
textField.setBackground(Color.RED);
}

formContainer.add(textField, BorderLayout.CENTER);

this.add(formContainer);
}
}

public void updateCurrentCell(JTextField textField, int index) {
if(updatingCell || deactivated) return;

Cell cell = new Cell();
cell.setRecord(currentRow);
cell.setField(index);

updatingCell = true;
imageState.setSelectedCell(cell);
updatingCell = false;
}

public void updateCellValue(JTextField textField, int index) {
if(updatingCell || deactivated) return;

Cell cell = new Cell();
cell.setRecord(currentRow);
cell.setField(index);

values[currentRow][index] = textField.getText();

if(hasSuggestion(textField.getText(), index)) {
textField.setBackground(Color.RED);
} else {
textField.setBackground(Color.WHITE);
}

updatingCell = true;
imageState.setValue(cell, textField.getText());
updatingCell = false;
}

public boolean hasSuggestion(String value, int column) {
if(value.equals("")) return false;
KnownData knownData = imageState.getKnownDataValues().get(column);

String[] words = knownData.getWordArray();

for(String val : words) {
if(val.toLowerCase().equals(value.toLowerCase())) return false;
}

return true;
}

private FocusListener generateFocusListener(final JTextField textField, final int index) {
return new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
updateCurrentCell(textField, index);
}

@Override
public void focusLost(FocusEvent e) {
updateCellValue(textField, index);
}
};
}

private void updateView() {
if(deactivated) return;

updatingCell = true;
for(int i = 0; i < this.getComponents().length; i++) {
JPanel formSet = (JPanel)this.getComponent(i);
JTextField form = (JTextField)formSet.getComponent(1);
form.setText(values[currentRow][i]);

if(hasSuggestion(form.getText(), i)) {
form.setBackground(Color.RED);
} else {
form.setBackground(Color.WHITE);
}
}
updatingCell = false;
}

public void setValue(String newValue, int row, int column) {
if(updatingCell || deactivated) return;

this.updateView();
this.repaint();
}

public void setCurrentCell(int row, int column) {
if(updatingCell || deactivated) return;

this.currentRow = row;

this.updateView();
this.repaint();

this.setFocus(column);
}

public void setCurrentCellForce() {
if(deactivated) return;

final Cell cell = imageState.getSelectedCell();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
setFocus(cell.getField());
}
});
}

public void setFocus(int columnField) {
if(deactivated) return;

// offset is x - 1, cause start at 0.
int column = columnField;

if(values.length == 0) return;

// get the column textField and request focus
JPanel formList = (JPanel)this.getComponent(column);
final JTextField form = (JTextField)formList.getComponent(1);

form.requestFocus();
}

public void setDeactivated(boolean deactivated) {
this.deactivated = deactivated;
}

}

+ 45
- 0
cs240/record-indexer/src/client/components/imagePanel/ImageCell.java View File

@@ -0,0 +1,45 @@
package client.components.imagePanel;

import java.awt.*;
import java.awt.geom.Rectangle2D;

public class ImageCell {

private double x;
private double y;
private double width;
private double height;
private boolean isSelected;
Rectangle2D.Double rectangle2D;

public ImageCell(Rectangle2D.Double rectangle2D) {
this.rectangle2D = rectangle2D;

this.x = rectangle2D.getBounds2D().getX();
this.y = rectangle2D.getBounds2D().getY();
this.width = this.x = rectangle2D.getBounds2D().getWidth();
this.height = this.x = rectangle2D.getBounds2D().getHeight();

this.isSelected = false;
}

public void paint(Graphics2D g2, boolean isSelected) {
if(isSelected) {
g2.setColor(new Color(0,119,204, 150));
} else {
g2.setColor(new Color(0,0,0, 0));
}
g2.fill(rectangle2D);
}

public boolean contains(double x, double y) {
return rectangle2D.contains(x, y);
}

public double getWidth() {
return width;
}

public void setWidth(double width) {
this.width = width;
}}

+ 174
- 0
cs240/record-indexer/src/client/components/imagePanel/ImageControl.java View File

@@ -0,0 +1,174 @@
package client.components.imagePanel;

import client.components.imagePanel.listeners.ImageControlsListener;
import client.persistence.ImageState;
import client.persistence.NewProjectListener;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

public class ImageControl extends JPanel {

private ArrayList<ImageControlsListener> imageControlsListeners;

private ImageState imageState;

private JButton zoomInButton;
private JButton zoomOutButton;
private JButton invertButton;
private JButton toggleHighlightsButton;
private JButton saveButton;
private JButton submitButton;

public ImageControl(ImageState imageState) {
this.imageState = imageState;