commit db88149138ba422c3aad9d9196dbe2bcd2ed14e9 Author: Skylar Date: Wed Aug 26 13:29:43 2015 -0600 Inital commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ff31bae --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/src/padkey \ No newline at end of file diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..618d5eb --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,229 @@ +Copyright (c) 2015, Netsyms Technologies. +All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + + + +This application also contains JSON.simple, under the Apache License: + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/build.xml b/build.xml new file mode 100644 index 0000000..94f2921 --- /dev/null +++ b/build.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + Builds, tests, and runs the project SyMAT Pad Viewer. + + + diff --git a/icon.png b/icon.png new file mode 100644 index 0000000..93adea1 Binary files /dev/null and b/icon.png differ diff --git a/lib/CopyLibs/org-netbeans-modules-java-j2seproject-copylibstask.jar b/lib/CopyLibs/org-netbeans-modules-java-j2seproject-copylibstask.jar new file mode 100644 index 0000000..eaf6790 Binary files /dev/null and b/lib/CopyLibs/org-netbeans-modules-java-j2seproject-copylibstask.jar differ diff --git a/lib/absolutelayout/AbsoluteLayout.jar b/lib/absolutelayout/AbsoluteLayout.jar new file mode 100644 index 0000000..40dfa69 Binary files /dev/null and b/lib/absolutelayout/AbsoluteLayout.jar differ diff --git a/lib/json-simple-1.1.1.jar b/lib/json-simple-1.1.1.jar new file mode 100644 index 0000000..66347a6 Binary files /dev/null and b/lib/json-simple-1.1.1.jar differ diff --git a/lib/nblibraries.properties b/lib/nblibraries.properties new file mode 100644 index 0000000..eb2041d --- /dev/null +++ b/lib/nblibraries.properties @@ -0,0 +1,7 @@ +libs.absolutelayout.classpath=\ + ${base}/absolutelayout/AbsoluteLayout.jar +libs.absolutelayout.displayName=Absolute Layout +libs.CopyLibs.classpath=\ + ${base}/CopyLibs/org-netbeans-modules-java-j2seproject-copylibstask.jar +libs.CopyLibs.displayName=CopyLibs Task +libs.CopyLibs.prop-version=2.0 diff --git a/manifest.mf b/manifest.mf new file mode 100644 index 0000000..328e8e5 --- /dev/null +++ b/manifest.mf @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +X-COMMENT: Main-Class will be added automatically by build + diff --git a/nbproject/build-impl.xml b/nbproject/build-impl.xml new file mode 100644 index 0000000..affc63c --- /dev/null +++ b/nbproject/build-impl.xml @@ -0,0 +1,1438 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set src.dir + Must set test.src.dir + Must set build.dir + Must set dist.dir + Must set build.classes.dir + Must set dist.javadoc.dir + Must set build.test.classes.dir + Must set build.test.results.dir + Must set build.classes.excludes + Must set dist.jar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + No tests executed. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set JVM to use for profiling in profiler.info.jvm + Must set profiler agent JVM arguments in profiler.info.jvmargs.agent + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + java -jar "${dist.jar.resolved}" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + Must select one file in the IDE or set run.class + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set debug.class + + + + + Must select one file in the IDE or set debug.class + + + + + Must set fix.includes + + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + Must select one file in the IDE or set profile.class + This target only works when run from inside the NetBeans IDE. + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + + + Must select some files in the IDE or set test.includes + + + + + Must select one file in the IDE or set run.class + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + Some tests failed; see details above. + + + + + + + + + Must select some files in the IDE or set test.includes + + + + Some tests failed; see details above. + + + + Must select some files in the IDE or set test.class + Must select some method in the IDE or set test.method + + + + Some tests failed; see details above. + + + + + Must select one file in the IDE or set test.class + + + + Must select one file in the IDE or set test.class + Must select some method in the IDE or set test.method + + + + + + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/nbproject/genfiles.properties b/nbproject/genfiles.properties new file mode 100644 index 0000000..37844e0 --- /dev/null +++ b/nbproject/genfiles.properties @@ -0,0 +1,8 @@ +build.xml.data.CRC32=f1252578 +build.xml.script.CRC32=27e95213 +build.xml.stylesheet.CRC32=8064a381@1.75.2.48 +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. +nbproject/build-impl.xml.data.CRC32=f1252578 +nbproject/build-impl.xml.script.CRC32=33b38239 +nbproject/build-impl.xml.stylesheet.CRC32=876e7a8f@1.75.2.48 diff --git a/nbproject/project.properties b/nbproject/project.properties new file mode 100644 index 0000000..1d9f593 --- /dev/null +++ b/nbproject/project.properties @@ -0,0 +1,79 @@ +annotation.processing.enabled=true +annotation.processing.enabled.in.editor=false +annotation.processing.processors.list= +annotation.processing.run.all.processors=true +annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output +application.title=SyMAT Pad Viewer +application.vendor=Skylar +build.classes.dir=${build.dir}/classes +build.classes.excludes=**/*.java,**/*.form +# This directory is removed when the project is cleaned: +build.dir=build +build.generated.dir=${build.dir}/generated +build.generated.sources.dir=${build.dir}/generated-sources +# Only compile against the classpath explicitly listed here: +build.sysclasspath=ignore +build.test.classes.dir=${build.dir}/test/classes +build.test.results.dir=${build.dir}/test/results +# Uncomment to specify the preferred debugger connection transport: +#debug.transport=dt_socket +debug.classpath=\ + ${run.classpath} +debug.test.classpath=\ + ${run.test.classpath} +# Files in build.classes.dir which should be excluded from distribution jar +dist.archive.excludes= +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.jar=${dist.dir}/SyMAT_Pad_Viewer.jar +dist.javadoc.dir=${dist.dir}/javadoc +endorsed.classpath= +excludes= +file.reference.json-simple-1.1.1.jar=lib/json-simple-1.1.1.jar +includes=** +jar.compress=false +javac.classpath=\ + ${file.reference.json-simple-1.1.1.jar}:\ + ${libs.absolutelayout.classpath} +# Space-separated list of extra javac options +javac.compilerargs= +javac.deprecation=false +javac.processorpath=\ + ${javac.classpath} +javac.source=1.8 +javac.target=1.8 +javac.test.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +javac.test.processorpath=\ + ${javac.test.classpath} +javadoc.additionalparam= +javadoc.author=false +javadoc.encoding=${source.encoding} +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle= +main.class=com.netsyms.symat.padview.GUI +manifest.file=manifest.mf +meta.inf.dir=${src.dir}/META-INF +mkdist.disabled=false +platform.active=default_platform +project.license=bsd +run.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +# Space-separated list of JVM arguments used when running the project. +# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value. +# To set system properties for unit tests define test-sys-prop.name=value: +run.jvmargs= +run.test.classpath=\ + ${javac.test.classpath}:\ + ${build.test.classes.dir} +source.encoding=UTF-8 +src.dir=src +test.src.dir=test diff --git a/nbproject/project.xml b/nbproject/project.xml new file mode 100644 index 0000000..1fd193a --- /dev/null +++ b/nbproject/project.xml @@ -0,0 +1,18 @@ + + + org.netbeans.modules.java.j2seproject + + + SyMAT Pad Viewer + + + + + + + + + .\lib\nblibraries.properties + + + diff --git a/pub/PadViewer_windows_1_0.exe b/pub/PadViewer_windows_1_0.exe new file mode 100644 index 0000000..7366f38 Binary files /dev/null and b/pub/PadViewer_windows_1_0.exe differ diff --git a/pub/md5sums b/pub/md5sums new file mode 100644 index 0000000..3575cc0 --- /dev/null +++ b/pub/md5sums @@ -0,0 +1 @@ +9947fbabf37cd9e01faa8653f49be351 *PadViewer_windows_1_0.exe diff --git a/pub/output.txt b/pub/output.txt new file mode 100644 index 0000000..100d1bc --- /dev/null +++ b/pub/output.txt @@ -0,0 +1,3 @@ +# List of generated media files. The columns are tab-separated: +# id | media file type | display name | media file path +26 windows Windows C:\Users\Skylar\Documents\NetBeansProjects\SyMAT Pad Viewer\pub\PadViewer_windows_1_0.exe diff --git a/pub/updates.xml b/pub/updates.xml new file mode 100644 index 0000000..a5c864f --- /dev/null +++ b/pub/updates.xml @@ -0,0 +1,32 @@ + + + + + + + + diff --git a/script.install4j b/script.install4j new file mode 100644 index 0000000..be229ce --- /dev/null +++ b/script.install4j @@ -0,0 +1,449 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${compiler:sys.publisher} + + + + + + + + + + + + + + + + + + + + + + + + false + + + false + + + true + + + true + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + sys.installationDir + + + + + + + context.getBooleanVariable("sys.confirmedUpdateInstallation") + + + + + + + + + + true + + + + + en + + C:/Users/Skylar/Documents/NetBeansProjects/SyMAT Pad Viewer/LICENSE.txt + + + + + + + + + + + + + + + + + + + + + !context.getBooleanVariable("sys.confirmedUpdateInstallation") + + + + + + + + + + + + sys.installationDir + + + + + + + context.getVariable("sys.responseFile") == null + + + + + + + + + + + + + + + + + + + + + + + ${compiler:sys.fullName} + + + + + !context.getBooleanVariable("sys.confirmedUpdateInstallation") + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SyMAT + + + ${i18n:UninstallerMenuEntry(${compiler:sys.fullName})} + + + + + !context.getBooleanVariable("sys.programGroupDisabled") + + + + + + + ${compiler:sys.fullName} ${compiler:sys.version} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${i18n:UninstallerMenuEntry(${compiler:sys.fullName})} + + + ${compiler:sys.publisher} + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/com/netsyms/symat/padview/128x128.png b/src/com/netsyms/symat/padview/128x128.png new file mode 100644 index 0000000..ac2ca5d Binary files /dev/null and b/src/com/netsyms/symat/padview/128x128.png differ diff --git a/src/com/netsyms/symat/padview/16x16.png b/src/com/netsyms/symat/padview/16x16.png new file mode 100644 index 0000000..1c78861 Binary files /dev/null and b/src/com/netsyms/symat/padview/16x16.png differ diff --git a/src/com/netsyms/symat/padview/24x24.png b/src/com/netsyms/symat/padview/24x24.png new file mode 100644 index 0000000..6d2591a Binary files /dev/null and b/src/com/netsyms/symat/padview/24x24.png differ diff --git a/src/com/netsyms/symat/padview/256x256.png b/src/com/netsyms/symat/padview/256x256.png new file mode 100644 index 0000000..1607634 Binary files /dev/null and b/src/com/netsyms/symat/padview/256x256.png differ diff --git a/src/com/netsyms/symat/padview/32x32.png b/src/com/netsyms/symat/padview/32x32.png new file mode 100644 index 0000000..7ef8ee0 Binary files /dev/null and b/src/com/netsyms/symat/padview/32x32.png differ diff --git a/src/com/netsyms/symat/padview/48x48.png b/src/com/netsyms/symat/padview/48x48.png new file mode 100644 index 0000000..530fd78 Binary files /dev/null and b/src/com/netsyms/symat/padview/48x48.png differ diff --git a/src/com/netsyms/symat/padview/512x512.png b/src/com/netsyms/symat/padview/512x512.png new file mode 100644 index 0000000..1667af2 Binary files /dev/null and b/src/com/netsyms/symat/padview/512x512.png differ diff --git a/src/com/netsyms/symat/padview/64x64.png b/src/com/netsyms/symat/padview/64x64.png new file mode 100644 index 0000000..04e16b0 Binary files /dev/null and b/src/com/netsyms/symat/padview/64x64.png differ diff --git a/src/com/netsyms/symat/padview/96x96.png b/src/com/netsyms/symat/padview/96x96.png new file mode 100644 index 0000000..d66d0e6 Binary files /dev/null and b/src/com/netsyms/symat/padview/96x96.png differ diff --git a/src/com/netsyms/symat/padview/Controls.form b/src/com/netsyms/symat/padview/Controls.form new file mode 100644 index 0000000..4c41940 --- /dev/null +++ b/src/com/netsyms/symat/padview/Controls.form @@ -0,0 +1,171 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/src/com/netsyms/symat/padview/Controls.java b/src/com/netsyms/symat/padview/Controls.java new file mode 100644 index 0000000..64286a2 --- /dev/null +++ b/src/com/netsyms/symat/padview/Controls.java @@ -0,0 +1,278 @@ +/* + * Copyright (c) 2015, Netsyms Technologies + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package com.netsyms.symat.padview; + +import java.io.File; +import java.io.IOException; +import javax.swing.JFileChooser; +import javax.swing.JOptionPane; +import javax.swing.filechooser.FileFilter; +import javax.swing.filechooser.FileNameExtensionFilter; + +/** + * + * @author Skylar + */ +public class Controls extends javax.swing.JPanel { + + private JFileChooser fc = new JFileChooser(); + + /** + * Creates new form Controls + */ + public Controls() { + FileFilter filter = new FileNameExtensionFilter("Plain Text (txt, text)", "txt", "text"); + fc.setFileFilter(filter); + fc.addChoosableFileFilter(filter); + fc.addChoosableFileFilter(new FileNameExtensionFilter( + "Javascript (syjs, js)", "syjs", "js")); + fc.addChoosableFileFilter(new FileNameExtensionFilter( + "Python (sypy, py)", "sypy", "py")); + initComponents(); + updateList(); + } + + public void saveFile(String contents) { + contents = contents.replaceAll("(?//GEN-BEGIN:initComponents + private void initComponents() { + + jLabel1 = new javax.swing.JLabel(); + addBtn = new javax.swing.JButton(); + jScrollPane1 = new javax.swing.JScrollPane(); + padPane = new javax.swing.JList(); + openBtn = new javax.swing.JButton(); + saveBtn = new javax.swing.JButton(); + jScrollPane2 = new javax.swing.JScrollPane(); + previewPane = new javax.swing.JTextArea(); + jLabel2 = new javax.swing.JLabel(); + previewBtn = new javax.swing.JButton(); + delBtn = new javax.swing.JButton(); + + jLabel1.setText("My Pads:"); + + addBtn.setText("+"); + addBtn.setToolTipText("Add pad by ID"); + addBtn.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + addBtnActionPerformed(evt); + } + }); + + padPane.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); + padPane.addListSelectionListener(new javax.swing.event.ListSelectionListener() { + public void valueChanged(javax.swing.event.ListSelectionEvent evt) { + padPaneValueChanged(evt); + } + }); + jScrollPane1.setViewportView(padPane); + + openBtn.setText("Open"); + openBtn.setToolTipText("Open pad for editing"); + openBtn.setEnabled(false); + openBtn.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + openBtnActionPerformed(evt); + } + }); + + saveBtn.setText("Save..."); + saveBtn.setToolTipText("Save pad locally"); + saveBtn.setEnabled(false); + saveBtn.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + saveBtnActionPerformed(evt); + } + }); + + previewPane.setEditable(false); + previewPane.setColumns(1); + previewPane.setRows(1); + previewPane.setTabSize(4); + jScrollPane2.setViewportView(previewPane); + + jLabel2.setText("Preview:"); + + previewBtn.setText("Preview"); + previewBtn.setToolTipText("Preview pad contents"); + previewBtn.setEnabled(false); + previewBtn.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + previewBtnActionPerformed(evt); + } + }); + + delBtn.setText("Delete"); + delBtn.setToolTipText("Remove pad from list"); + delBtn.setEnabled(false); + delBtn.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + delBtnActionPerformed(evt); + } + }); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 132, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() + .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 69, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(addBtn))) + .addGap(6, 6, 6) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(delBtn, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(previewBtn, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(saveBtn, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(openBtn, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 79, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel2) + .addGap(0, 296, Short.MAX_VALUE)) + .addComponent(jScrollPane2))) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jLabel1) + .addComponent(jLabel2) + .addComponent(addBtn)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) + .addGroup(layout.createSequentialGroup() + .addComponent(openBtn) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(saveBtn) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(previewBtn) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(delBtn) + .addContainerGap()) + .addComponent(jScrollPane2))) + ); + }// //GEN-END:initComponents + + private void addBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addBtnActionPerformed + String id = JOptionPane.showInputDialog(this, + "What is the pad ID?", + "Add Pad", + JOptionPane.QUESTION_MESSAGE); + if (id != null && !id.equals("")) { + if (id.contains("pad.symatapp.com/p/")) { + id = id.substring(id.lastIndexOf('/') + 1); + } + PadUtils.addPad(id); + } + updateList(); + }//GEN-LAST:event_addBtnActionPerformed + + private String getSelectedPad() { + return padPane.getSelectedValue().toString(); + } + + private void updateList() { + padPane.setListData(PadUtils.getPads()); + } + + private void padPaneValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_padPaneValueChanged + // Enable/disable action buttons to prevent errors. + boolean enable = true; + if (padPane.getSelectedValue() == null) { + enable = false; + } + openBtn.setEnabled(enable); + saveBtn.setEnabled(enable); + previewBtn.setEnabled(enable); + delBtn.setEnabled(enable); + }//GEN-LAST:event_padPaneValueChanged + + private void openBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openBtnActionPerformed + GUI.loadPad(getSelectedPad()); + }//GEN-LAST:event_openBtnActionPerformed + + private void saveBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveBtnActionPerformed + saveFile(PadUtils.getPad(getSelectedPad())); + updateList(); + }//GEN-LAST:event_saveBtnActionPerformed + + private void previewBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_previewBtnActionPerformed + previewPane.setText(PadUtils.getPad(getSelectedPad())); + previewPane.setCaretPosition(0); + + updateList(); + }//GEN-LAST:event_previewBtnActionPerformed + + private void delBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_delBtnActionPerformed + int ans = JOptionPane.showConfirmDialog(this, + "Remove pad from list? It will not be removed from the server.", + "Delete?", + JOptionPane.OK_CANCEL_OPTION); + if (ans == JOptionPane.OK_OPTION) { + PadUtils.delPad(getSelectedPad()); + } + updateList(); + }//GEN-LAST:event_delBtnActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton addBtn; + private javax.swing.JButton delBtn; + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JScrollPane jScrollPane2; + private javax.swing.JButton openBtn; + private javax.swing.JList padPane; + private javax.swing.JButton previewBtn; + private javax.swing.JTextArea previewPane; + private javax.swing.JButton saveBtn; + // End of variables declaration//GEN-END:variables +} diff --git a/src/com/netsyms/symat/padview/Debug.java b/src/com/netsyms/symat/padview/Debug.java new file mode 100644 index 0000000..2901ed7 --- /dev/null +++ b/src/com/netsyms/symat/padview/Debug.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2015, Netsyms Technologies + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package com.netsyms.symat.padview; + +/** + * This class handles debug logging, so it's easy to disable. + * + * @author Skylar + */ +public class Debug { + + // If output should be on or off + public static boolean debug = true; + + /** + * Turn debug output on and off. + * + * @param b + */ + public static void setDebug(boolean b) { + debug = b; + } + + /** + * Check if debug output is enabled. + * + * @return true if it is. + */ + public static boolean getDebug() { + return debug; + } + + /** + * Call System.out.println(data) if debug output enabled. + * + * @param data Data to print. + */ + public static void println(Object data) { + if (debug) { + System.out.println(data); + } + } + + /** + * Call System.err.println(data) if debug output enabled. + * + * @param data Data to print. + */ + public static void printerr(Object data) { + if (debug) { + System.err.println(data); + } + } + + /** + * Call e.printStackTrace() if debug output enabled. + * + * @param e an Exception. + */ + @SuppressWarnings(value = {"CallToPrintStackTrace"}) + public static void stacktrace(Exception e) { + if (debug) { + e.printStackTrace(); + } + } +} diff --git a/src/com/netsyms/symat/padview/FileUtils.java b/src/com/netsyms/symat/padview/FileUtils.java new file mode 100644 index 0000000..89bddad --- /dev/null +++ b/src/com/netsyms/symat/padview/FileUtils.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2015, Netsyms Technologies + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package com.netsyms.symat.padview; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Scanner; +import javax.swing.JFileChooser; +import javax.swing.filechooser.FileNameExtensionFilter; + +/** + * File Utilities. + * + * @author Skylar + */ +public class FileUtils { + + /** + * Read a UTF-8 text file. + * + * @param path Where is the file? + * @return The file contents. + * @throws IOException + */ + public static String readFile(String path) + throws IOException { + byte[] encoded = Files.readAllBytes(Paths.get(path)); + return new String(encoded, StandardCharsets.UTF_8); + } + + /** + * Returns the selected file from a JFileChooser, including the extension + * from the file filter. + * + * Credit to http://stackoverflow.com/users/964243/boann + * + * @param c The JFileChooser to extract from. + * @return duh. + */ + public static File getFileWithExtension(JFileChooser c) { + File file = c.getSelectedFile(); + if (c.getFileFilter() instanceof FileNameExtensionFilter) { + String[] exts = ((FileNameExtensionFilter) c.getFileFilter()).getExtensions(); + String nameLower = file.getName().toLowerCase(); + for (String ext : exts) { // check if it already has a valid extension + if (nameLower.endsWith('.' + ext.toLowerCase())) { + return file; // if yes, return as-is + } + } + // if not, append the first extension from the selected filter + file = new File(file.toString() + '.' + exts[0]); + } + return file; + } + + public static void saveFile(String content, String path, boolean addToRecent) + throws IOException { + try (PrintStream out = new PrintStream(new FileOutputStream(path))) { + out.print(content); + } + } + + /** + * Get an MD5 hash. + * + * http://stackoverflow.com/a/6565597/2534036 + * + * @param md5 the text to hash. + * @return + */ + public static String MD5(String md5) { + try { + java.security.MessageDigest md + = java.security.MessageDigest.getInstance("MD5"); + byte[] array = md.digest(md5.getBytes()); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < array.length; ++i) { + sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).substring(1, 3)); + } + return sb.toString(); + } catch (java.security.NoSuchAlgorithmException e) { + } + return null; + } + + public static String getUrl(String url) throws MalformedURLException, IOException { + String out; + try (Scanner sc = new Scanner(new URL(url).openStream(), "UTF-8")) { + out = sc.useDelimiter("\\A").next(); + } + return out; + } +} diff --git a/src/com/netsyms/symat/padview/GUI.form b/src/com/netsyms/symat/padview/GUI.form new file mode 100644 index 0000000..02d9a98 --- /dev/null +++ b/src/com/netsyms/symat/padview/GUI.form @@ -0,0 +1,58 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/com/netsyms/symat/padview/GUI.java b/src/com/netsyms/symat/padview/GUI.java new file mode 100644 index 0000000..32d26f3 --- /dev/null +++ b/src/com/netsyms/symat/padview/GUI.java @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2015, Netsyms Technologies + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package com.netsyms.symat.padview; + +import java.awt.BorderLayout; +import java.awt.Image; +import java.util.ArrayList; +import javax.swing.ImageIcon; + +/** + * + * @author Skylar + */ +public class GUI extends javax.swing.JFrame { + + public static ArrayList logo = new ArrayList<>(); + public static WebView web; + public static Controls controls; + + public static final String VERSION = "1.0"; + public static final int VERSIONCODE = 1; + public static final String SYMAT = "SyMAT"; + public static final String PRODUCT = "Pad Viewer"; + + /** + * Creates new form GUI + */ + public GUI() { + initComponents(); + setIconImages(logo); + web = new WebView(); + controls = new Controls(); + add(controls, BorderLayout.NORTH); + add(web, BorderLayout.CENTER); + web.setVisible(true); + controls.setVisible(true); + } + + public static void loadPad(String pad) { + web.loadURL(PadUtils.PADS_URL + "/p/" + pad, pad); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + jPanel1 = new javax.swing.JPanel(); + statusLbl = new javax.swing.JLabel(); + + setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); + setTitle("SyMAT Pad Viewer"); + setPreferredSize(new java.awt.Dimension(600, 600)); + + jPanel1.setPreferredSize(new java.awt.Dimension(400, 20)); + jPanel1.setLayout(new java.awt.BorderLayout()); + + statusLbl.setText("Welcome!"); + statusLbl.setToolTipText(""); + jPanel1.add(statusLbl, java.awt.BorderLayout.CENTER); + + getContentPane().add(jPanel1, java.awt.BorderLayout.PAGE_END); + + pack(); + setLocationRelativeTo(null); + }// //GEN-END:initComponents + + /** + * @param args the command line arguments + */ + public static void main(String args[]) { + /* Set the Nimbus look and feel */ + // + /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel. + * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html + */ + try { + for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { + if ("Nimbus".equals(info.getName())) { + javax.swing.UIManager.setLookAndFeel(info.getClassName()); + break; + } + } + } catch (ClassNotFoundException ex) { + java.util.logging.Logger.getLogger(GUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } catch (InstantiationException ex) { + java.util.logging.Logger.getLogger(GUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } catch (IllegalAccessException ex) { + java.util.logging.Logger.getLogger(GUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } catch (javax.swing.UnsupportedLookAndFeelException ex) { + java.util.logging.Logger.getLogger(GUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } + // + + // Set icon + String[] sizes = {"16", "24", "32", "48", "64", "96", "128", "256", "512"}; + for (String s : sizes) { + logo.add(new ImageIcon( + GUI.class.getResource(s + "x" + s + ".png")).getImage()); + } + + /* Create and display the form */ + java.awt.EventQueue.invokeLater(new Runnable() { + public void run() { + new SplashScreen().setVisible(true); + } + }); + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + public static javax.swing.JPanel jPanel1; + public static javax.swing.JLabel statusLbl; + // End of variables declaration//GEN-END:variables +} diff --git a/src/com/netsyms/symat/padview/PadUtils.java b/src/com/netsyms/symat/padview/PadUtils.java new file mode 100644 index 0000000..ac89383 --- /dev/null +++ b/src/com/netsyms/symat/padview/PadUtils.java @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2015, Netsyms Technologies + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package com.netsyms.symat.padview; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.util.Random; +import javax.swing.JOptionPane; +import org.etherpad_lite_client.EPLiteClient; +import org.etherpad_lite_client.EPLiteException; + +/** + * + * @author Skylar + */ +public class PadUtils { + + public static final String PADS_URL = "http://pad.symatapp.com"; + + /** + * Add the given pad ID to the local pad list. + * + * @param id the pad ID. + */ + public static void addPad(String id) { + String pads = PrefStorage.getSetting("pads"); + + // Check for dupes + for (String p : pads.split("\\|")) { + if (p.equals(id)) { + return; + } + } + + if (pads.equals("")) { + pads = id; + } else { + pads += "|" + id; + } + PrefStorage.saveSetting("pads", pads); + } + + /** + * Delete the pad with the given ID from local memory. + *
It will still exist online. + * + * @param id the pad ID. + */ + public static void delPad(String id) { + String pads = PrefStorage.getSetting("pads"); + String result = ""; + int i = 0; + for (String pad : pads.split("\\|")) { + if (!pad.equals(id)) { + if (i > 0) { + result += "|"; + } + result += pad; + i++; + } + } + + PrefStorage.saveSetting("pads", result); + } + + /** + * Get an array of saved pads. + * + * @return String[] of pad IDs + */ + public static String[] getPads() { + String pads = PrefStorage.getSetting("pads"); + if (!pads.equals("")) { + if (pads.contains("|")) { + return pads.split("\\|"); + } else { + String[] padlist = {pads}; + return padlist; + } + } else { + String[] padlist = {}; + return padlist; + } + } + + /** + * Create a new pad on the server with the given ID. + * + * @param id The pad ID to create. If blank is auto-generated. + * @param content Text to initialize the pad with. + * @return Created pad ID. + * @throws Exception if things break. + */ + public static String genPad(String id, String content) throws Exception { + // Generate ID if blank + if (id.equals("")) { + id = genID(); + } + + // Create pad with given text. + try { + getClient().createPad(id, content); + } catch (EPLiteException ex) { + getClient().setText(id, content); + } + return id; + } + + /** + * Generate a random pad ID with length 15. + *
There are about 1.217 x 10^26 possibilities (121 septillion). + *
If this starts giving out used IDs, I'll be too rich to care. + * + * @return the ID. + */ + public static String genID() { + int length = 15; + String[] chars = ("0123456789" + + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + + "abcdefghijklmnopqrstuvwxyz").split(""); + String out = ""; + Random rng = new Random(); + + for (int i = 0; i < length; i++) { + out += chars[rng.nextInt(chars.length)]; + } + + return out; + } + + /** + * Get a client for the pad API. + * + * @return the client. + * @throws Exception if things break. + */ + public static EPLiteClient getClient() throws Exception { + String apikey; + // Enable key change without full SyMAT update + if (!PrefStorage.getSetting("padkey-override", "").equals("")) { + apikey = PrefStorage.getSetting("padkey-override", ""); + } else { + // Load the API key from a file, so it's not included with Git. + BufferedReader reader = new BufferedReader( + new InputStreamReader( + PadUtils.class + .getResourceAsStream("/padkey"))); + apikey = reader.readLine(); + } + // New client + return new EPLiteClient(PADS_URL, apikey); + } + + /** + * Get the pad text. + * + * @param id the pad ID. + * @return the text, or error message. + */ + public static String getPad(String id) { + String text = ""; + try { + text = getClient().getText(id).getOrDefault("text", "").toString(); + } catch (Exception ex) { + text = "Error: " + ex.getMessage(); + } + return text; + } + + /** + * Set pad text. + * + * @param id Pad ID + * @param content Pad text + */ + public static void setPad(String id, String content) { + try { + getClient().setText(id, content); + } catch (Exception ex) { + JOptionPane.showMessageDialog( + null, + "Could not sync pad contents: " + ex.getMessage(), + "Error", + JOptionPane.ERROR_MESSAGE); + } + } + + /** + * Delete the given pad ID. + * + * @param id the pad ID. + * @param purge If true will delete from server also. + */ + public static void delPad(String id, boolean purge) { + delPad(id); + if (purge) { + try { + getClient().deletePad(id); + } catch (Exception ex) { + // Meh. No big deal. + } + } + } +} diff --git a/src/com/netsyms/symat/padview/PrefStorage.java b/src/com/netsyms/symat/padview/PrefStorage.java new file mode 100644 index 0000000..77e2cbf --- /dev/null +++ b/src/com/netsyms/symat/padview/PrefStorage.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2015, Netsyms Technologies + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package com.netsyms.symat.padview; + +import java.util.ArrayList; +import java.util.List; +import java.util.prefs.BackingStoreException; +import java.util.prefs.Preferences; + +/** + * + * @author Skylar Ittner + */ +public class PrefStorage { + + private static final Preferences prefs = Preferences.userNodeForPackage(PrefStorage.class); + + public static void saveSetting(String key, String value) { + prefs.put(key, value); + } + + public static boolean isset(String key) { + return !getSetting(key, "NULL").equals("NULL"); + } + + public static void unset(String key) { + saveSetting(key, ""); + save(); + prefs.remove(key); + save(); + } + + public static String getSetting(String key) { + return prefs.get(key, ""); + } + + public static String getSetting(String key, String emptyResponse) { + return prefs.get(key, emptyResponse); + } + + public static boolean save() { + try { + prefs.flush(); + prefs.sync(); + } catch (BackingStoreException ex) { + System.err.println("Settings could not be saved!"); + return false; + } + return true; + } + + /** + * Wipe all settings. + * + * @throws java.util.prefs.BackingStoreException + */ + public static void wipe() throws BackingStoreException { + prefs.clear(); + } +} diff --git a/src/com/netsyms/symat/padview/SplashScreen.form b/src/com/netsyms/symat/padview/SplashScreen.form new file mode 100644 index 0000000..e6a24b6 --- /dev/null +++ b/src/com/netsyms/symat/padview/SplashScreen.form @@ -0,0 +1,80 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/com/netsyms/symat/padview/SplashScreen.java b/src/com/netsyms/symat/padview/SplashScreen.java new file mode 100644 index 0000000..02a35a0 --- /dev/null +++ b/src/com/netsyms/symat/padview/SplashScreen.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2015, Netsyms Technologies + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package com.netsyms.symat.padview; + +import static com.netsyms.symat.padview.GUI.logo; + +/** + * + * @author Skylar + */ +public class SplashScreen extends javax.swing.JFrame { + + public SplashScreen me; + + /** + * Creates new form SplashScreen + */ + public SplashScreen() { + initComponents(); + setIconImages(logo); + me = this; + + new java.util.Timer().schedule( + new java.util.TimerTask() { + @Override + public void run() { + new GUI().setVisible(true); + me.dispose(); + } + }, + 3000 + ); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + jLabel3 = new javax.swing.JLabel(); + jLabel1 = new javax.swing.JLabel(); + jLabel4 = new javax.swing.JLabel(); + jLabel2 = new javax.swing.JLabel(); + + setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); + setUndecorated(true); + setResizable(false); + getContentPane().setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout()); + + jLabel3.setText("Netsyms Technologies"); + getContentPane().add(jLabel3, new org.netbeans.lib.awtextra.AbsoluteConstraints(10, 270, 130, 30)); + + jLabel1.setFont(new java.awt.Font("Tahoma", 0, 24)); // NOI18N + jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + jLabel1.setText("" + + GUI.SYMAT + + " " + + GUI.PRODUCT + + "" + ); + getContentPane().add(jLabel1, new org.netbeans.lib.awtextra.AbsoluteConstraints(0, 180, 400, -1)); + + jLabel4.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING); + jLabel4.setText("symatapp.com"); + getContentPane().add(jLabel4, new org.netbeans.lib.awtextra.AbsoluteConstraints(280, 270, 110, 30)); + + jLabel2.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/netsyms/symat/padview/splash.png"))); // NOI18N + getContentPane().add(jLabel2, new org.netbeans.lib.awtextra.AbsoluteConstraints(0, 0, -1, -1)); + + pack(); + setLocationRelativeTo(null); + }// //GEN-END:initComponents + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel1; + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel jLabel4; + // End of variables declaration//GEN-END:variables +} diff --git a/src/com/netsyms/symat/padview/WebView.form b/src/com/netsyms/symat/padview/WebView.form new file mode 100644 index 0000000..ac30e69 --- /dev/null +++ b/src/com/netsyms/symat/padview/WebView.form @@ -0,0 +1,20 @@ + + +
+ + + + + + + + + + + + + + + + + diff --git a/src/com/netsyms/symat/padview/WebView.java b/src/com/netsyms/symat/padview/WebView.java new file mode 100644 index 0000000..a8af5fa --- /dev/null +++ b/src/com/netsyms/symat/padview/WebView.java @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2015, Netsyms Technologies + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package com.netsyms.symat.padview; + +import java.awt.BorderLayout; +import javafx.application.Platform; +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; +import javafx.collections.ObservableList; +import javafx.concurrent.Worker; +import javafx.embed.swing.JFXPanel; +import javafx.event.EventHandler; +import javafx.scene.Group; +import javafx.scene.Node; +import javafx.scene.Scene; +import javafx.scene.web.PromptData; +import javafx.scene.web.WebEngine; +import javafx.scene.web.WebEvent; +import javafx.util.Callback; +import javax.swing.JOptionPane; + +/** + * + * @author Skylar + */ +public class WebView extends javax.swing.JPanel { + + private javafx.scene.web.WebView browser; + private WebEngine webEngine; + private JFXPanel jfxPanel; + private Group root; + private Scene scene; + + private String loaded = ""; + + /** + * Creates new form WebView + */ + public WebView() { + initComponents(); + jfxPanel = new JFXPanel(); + Platform.runLater(new Runnable() { + @Override + public void run() { + browser = new javafx.scene.web.WebView(); + browser.setPrefSize(getWidth(), getHeight()); + root = new Group(); + scene = new Scene(root); + ObservableList children = root.getChildren(); + children.add(browser); + jfxPanel.setScene(scene); + webEngine = browser.getEngine(); + webEngine.getLoadWorker().stateProperty().addListener( + new ChangeListener() { + @Override + public void changed(ObservableValue ov, Worker.State oldState, Worker.State newState) { + if (newState == Worker.State.RUNNING) { + GUI.statusLbl.setText("Loading..."); + } else if (newState == Worker.State.SCHEDULED + || newState == Worker.State.READY) { + + } else { + GUI.statusLbl.setText(loaded); + } + } + }); + webEngine.setOnAlert( + new EventHandler>() { + @Override + public void handle(WebEvent t) { + JOptionPane.showMessageDialog(jfxPanel, t.getData(), "Message from webpage", JOptionPane.INFORMATION_MESSAGE); + } + }); + + webEngine.setPromptHandler( + new Callback() { + @Override + public String call(PromptData p) { + return JOptionPane.showInputDialog(jfxPanel, p.getMessage(), "Question from webpage", JOptionPane.QUESTION_MESSAGE); + } + }); + webEngine.setConfirmHandler( + new Callback() { + + @Override + public Boolean call(String p) { + return (JOptionPane.showConfirmDialog( + jfxPanel, + p, + "Question from webpage", + JOptionPane.OK_CANCEL_OPTION) + == JOptionPane.OK_OPTION); + } + + }); + webEngine.setUserAgent("Mozilla/5.0 SyMAT/PadView1.0"); + } + }); + add(jfxPanel, BorderLayout.CENTER); + loadHomepage(); + } + + public void loadURL(final String url, String finishedText) { + loaded = finishedText; + Platform.runLater(new Runnable() { + @Override + public void run() { + webEngine.load(url); + } + }); + } + + public void loadHomepage() { + String homepage = "" + + "" + + "" + + "" + + "" + + "" + + "" + + "

" + GUI.SYMAT + " " + GUI.PRODUCT + " " + GUI.VERSION + "

" + + "

To add a pad, press the + button above, and enter the pad ID or URL." + + "
To preview a pad before loading it, press the Preview button." + + "
To open a pad for viewing or editing, press Open." + + "
To save a pad's contents to your computer, press Save..." + + "

" + + "" + + ""; + Platform.runLater(new Runnable() { + @Override + public void run() { + webEngine.loadContent(homepage); + } + }); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + addComponentListener(new java.awt.event.ComponentAdapter() { + public void componentResized(java.awt.event.ComponentEvent evt) { + formComponentResized(evt); + } + }); + setLayout(new java.awt.BorderLayout()); + }// //GEN-END:initComponents + + private void formComponentResized(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_formComponentResized + Platform.runLater(new Runnable() { + @Override + public void run() { + jfxPanel.setSize(getWidth(), getHeight()); + browser.setPrefSize(getWidth(), getHeight()); + browser.resize(getWidth(), getHeight()); + } + }); + }//GEN-LAST:event_formComponentResized + + + // Variables declaration - do not modify//GEN-BEGIN:variables + // End of variables declaration//GEN-END:variables +} diff --git a/src/com/netsyms/symat/padview/splash.png b/src/com/netsyms/symat/padview/splash.png new file mode 100644 index 0000000..aa044e5 Binary files /dev/null and b/src/com/netsyms/symat/padview/splash.png differ diff --git a/src/org/etherpad_lite_client/EPLiteClient.java b/src/org/etherpad_lite_client/EPLiteClient.java new file mode 100644 index 0000000..e941f1f --- /dev/null +++ b/src/org/etherpad_lite_client/EPLiteClient.java @@ -0,0 +1,639 @@ +package org.etherpad_lite_client; + +import java.util.Date; +import java.util.HashMap; + +/** + * A client for talking to Etherpad Lite's HTTP JSON API.
+ *
+ * Example:
+ *
+ * + * EPLiteClient api = new EPLiteClient("http://etherpad.mysite.com", "FJ7jksalksdfj83jsdflkj");
+ * HashMap pad = api.getText("my_pad");
+ * String pad = pad.get("text").toString(); + *
+ */ +public class EPLiteClient { + /** + * The Etherpad Lite API version this client targets by default + */ + public static final String DEFAULT_API_VERSION = "1.2.11"; + + /** + * The connection object + */ + public EPLiteConnection connection; + + /** + * Initializes a new org.etherpad_lite_client.EPLiteClient object. + * The default Etherpad Lite API version (in DEFAULT_API_VERSION) will be used. + * + * @param url an absolute url, including protocol, to the EPL api + * @param apiKey the API Key + */ + public EPLiteClient(String url, String apiKey) { + this.connection = new EPLiteConnection(url, apiKey, DEFAULT_API_VERSION); + } + + /** + * Initializes a new org.etherpad_lite_client.EPLiteClient object. + * The specified Etherpad Lite API version will be used. + * + * @param url an absolute url, including protocol, to the EPL api + * @param apiKey the API Key + * @param apiVersion the API version + */ + public EPLiteClient(String url, String apiKey, String apiVersion) { + this.connection = new EPLiteConnection(url, apiKey, apiVersion); + } + + // Groups + // Pads may belong to a group. These pads are not considered "public", and won't be available through the Web UI without a session. + + /** + * Creates a new Group. The group id is returned in "groupID" in the HashMap. + * + * @return HashMap + */ + public HashMap createGroup() { + return this.connection.post("createGroup"); + } + + /** + * Creates a new Group for groupMapper if one doesn't already exist. Helps you map your application's groups to Etherpad Lite's groups. + * The group id is returned in "groupID" in the HashMap. + * + * @param groupMapper your group mapper string + * @return HashMap + */ + public HashMap createGroupIfNotExistsFor(String groupMapper) { + HashMap args = new HashMap(); + args.put("groupMapper", groupMapper); + return this.connection.post("createGroupIfNotExistsFor", args); + } + + /** + * Delete group. + * + * @param groupID string + */ + public void deleteGroup(String groupID) { + HashMap args = new HashMap(); + args.put("groupID", groupID); + this.connection.post("deleteGroup", args); + } + + /** + * List all the padIDs in a group. They will be in an array inside "padIDs". + * + * @param groupID string + * @return HashMap + */ + public HashMap listPads(String groupID) { + HashMap args = new HashMap(); + args.put("groupID", groupID); + return this.connection.get("listPads", args); + } + + /** + * Create a pad in this group. + * + * @param groupID string + * @param padName string + */ + public HashMap createGroupPad(String groupID, String padName) { + HashMap args = new HashMap(); + args.put("groupID", groupID); + args.put("padName", padName); + return this.connection.post("createGroupPad", args); + } + + /** + * Create a pad in this group. + * + * @param groupID string + * @param padName string + * @param text string + */ + public void createGroupPad(String groupID, String padName, String text) { + HashMap args = new HashMap(); + args.put("groupID", groupID); + args.put("padName", padName); + args.put("text", text); + this.connection.post("createGroupPad", args); + } + + /** + * Lists all existing groups. The group ids are returned in "groupIDs". + * + * @return HashMap + */ + public HashMap listAllGroups() { + return this.connection.get("listAllGroups"); + } + + // Authors + // These authors are bound to the attributes the users choose (color and name). The author id is returned in "authorID". + + /** + * Create a new author. + * + * @return HashMap + */ + public HashMap createAuthor() { + return this.connection.post("createAuthor"); + } + + /** + * Create a new author with the given name. The author id is returned in "authorID". + * + * @param name string + * @return HashMap + */ + public HashMap createAuthor(String name) { + HashMap args = new HashMap(); + args.put("name", name); + return this.connection.post("createAuthor", args); + } + + /** + * Creates a new Author for authorMapper if one doesn't already exist. Helps you map your application's authors to Etherpad Lite's authors. + * The author id is returned in "authorID". + * + * @param authorMapper string + * @return HashMap + */ + public HashMap createAuthorIfNotExistsFor(String authorMapper) { + HashMap args = new HashMap(); + args.put("authorMapper", authorMapper); + return this.connection.post("createAuthorIfNotExistsFor", args); + } + + /** + * Creates a new Author for authorMapper if one doesn't already exist. Helps you map your application's authors to Etherpad Lite's authors. + * The author id is returned in "authorID". + * + * @param authorMapper string + * @param name string + * @return HashMap + */ + public HashMap createAuthorIfNotExistsFor(String authorMapper, String name) { + HashMap args = new HashMap(); + args.put("authorMapper", authorMapper); + args.put("name", name); + return this.connection.post("createAuthorIfNotExistsFor", args); + } + + /** + * List the ids of pads the author has edited. They will be in an array inside "padIDs". + * + * @param authorId the authors's id string + * @return HashMap + */ + public HashMap listPadsOfAuthor(String authorId) { + HashMap args = new HashMap(); + args.put("authorID", authorId); + return this.connection.get("listPadsOfAuthor", args); + } + + /** + * Returns the Author Name of the author. + * + * @param authorId the author's id string + * @return String + */ + public String getAuthorName(String authorId) { + HashMap args = new HashMap(); + args.put("authorID", authorId); + return this.connection.get("getAuthorName", args).toString(); + } + + // Sessions + // Sessions can be created between a group and an author. This allows an author to access more than one group. The sessionID will be set as a + // cookie to the client and is valid until a certain date. Only users with a valid session for this group, can access group pads. You can create a + // session after you authenticated the user at your web application, to give them access to the pads. You should save the sessionID of this session + // and delete it after the user logged out. + + /** + * Create a new session for the given author in the given group, valid until the given UNIX time. + * The session id will be returned in "sessionID".
+ *
+ * Example:
+ *
+ * + * import java.util.Date;
+ * ...
+ * Date now = new Date();
+ * long in1Hour = (now.getTime() + (60L * 60L * 1000L) / 1000L);
+ * String sessID1 = api.createSession(groupID, authorID, in1Hour).get("sessionID").toString(); + *
+ * + * @param groupID string + * @param authorID string + * @param validUntil long UNIX timestamp in seconds + * @return HashMap + */ + public HashMap createSession(String groupID, String authorID, long validUntil) { + HashMap args = new HashMap(); + args.put("groupID", groupID); + args.put("authorID", authorID); + args.put("validUntil", String.valueOf(validUntil)); + return this.connection.post("createSession", args); + } + + /** + * Create a new session for the given author in the given group valid for the given number of hours. + * The session id will be returned in "sessionID".
+ *
+ * Example:
+ *
+ * + * // in 2 hours
+ * String sessID1 = api.createSession(groupID, authorID, 2).get("sessionID").toString(); + *
+ * + * @param groupID string + * @param authorID string + * @param validUntil int length of session in hours + * @return HashMap + */ + public HashMap createSession(String groupID, String authorID, int length) { + long inNHours = ((new Date()).getTime() + ((long)length * 60L * 60L * 1000L)) / 1000L; + return this.createSession(groupID, authorID, inNHours); + } + + /** + * Create a new session for the given author in the given group, valid until the given datetime. + * The session id will be returned in "sessionID".
+ *
+ * Example:
+ *
+ * + * import java.util.Date;
+ * import java.text.DateFormat;
+ * import java.text.SimpleDateFormat;
+ * import java.util.TimeZone;
+ * ...
+ * DateFormat dfm = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ * dfm.setTimeZone(TimeZone.getTimeZone("GMT-5"));
+ * Date longTime = dfm.parse("2056-01-15 20:15:00");
+ * String sessID = api.createSession(groupID, authorID, longTime).get("sessionID").toString(); + *
+ * + * @param groupID string + * @param authorID string + * @param validUntil Date + * @return HashMap + */ + public HashMap createSession(String groupID, String authorID, Date validUntil) { + long seconds = validUntil.getTime() / 1000L; + return this.createSession(groupID, authorID, seconds); + } + + /** + * Delete a session. + * + * @param sessionID string + */ + public void deleteSession(String sessionID) { + HashMap args = new HashMap(); + args.put("sessionID", sessionID); + this.connection.post("deleteSession", args); + } + + /** + * Returns information about a session: authorID, groupID and validUntil. + * + * @param sessionID string + * @return HashMap + */ + public HashMap getSessionInfo(String sessionID) { + HashMap args = new HashMap(); + args.put("sessionID", sessionID); + return this.connection.get("getSessionInfo", args); + } + + /** + * List all the sessions IDs in a group. Returned as a HashMap of sessionIDs keys, with values of HashMaps containing + * groupID, authorID, and validUntil. + * + * @param groupID string + * @return HashMap + */ + public HashMap listSessionsOfGroup(String groupID) { + HashMap args = new HashMap(); + args.put("groupID", groupID); + return this.connection.get("listSessionsOfGroup", args); + } + + /** + * List all the sessions IDs belonging to an author. Returned as a HashMap of sessionIDs keys, with values of HashMaps containing + * groupID, authorID, and validUntil. + * + * @param authorID string + * @return HashMap + */ + public HashMap listSessionsOfAuthor(String authorID) { + HashMap args = new HashMap(); + args.put("authorID", authorID); + return this.connection.get("listSessionsOfAuthor", args); + } + + // Pad content + + /** + * Returns a list of all pads. + * + * @return HashMap + */ + public HashMap listAllPads() { + return this.connection.get("listAllPads"); + } + + /** + * Returns a HashMap containing the latest revision of the pad's text. + * The text is stored under "text". + * + * @param padId the pad's id string + * @return HashMap + */ + public HashMap getText(String padId) { + HashMap args = new HashMap(); + args.put("padID", padId); + return this.connection.get("getText", args); + } + + /** + * Returns a HashMap containing the a specific revision of the pad's text. + * The text is stored under "text". + * + * @param padId the pad's id string + * @param rev the revision number + * @return HashMap + */ + public HashMap getText(String padId, int rev) { + HashMap args = new HashMap(); + args.put("padID", padId); + args.put("rev", new Integer(rev)); + return this.connection.get("getText", args); + } + + /** + * Creates a new revision with the given text (or creates a new pad). + * + * @param padId the pad's id string + * @param text the pad's new text + */ + public void setText(String padId, String text) { + HashMap args = new HashMap(); + args.put("padID", padId); + args.put("text", text); + this.connection.post("setText", args); + } + + /** + * Returns a HashMap containing the current revision of the pad's text as HTML. + * The html is stored under "html". + * + * @param padId the pad's id string + * @return HashMap + */ + public HashMap getHTML(String padId) { + HashMap args = new HashMap(); + args.put("padID", padId); + return this.connection.get("getHTML", args); + } + + /** + * Returns a HashMap containing the a specific revision of the pad's text as HTML. + * The html is stored under "html". + * + * @param padId the pad's id string + * @param rev the revision number + * @return HashMap + */ + public HashMap getHTML(String padId, int rev) { + HashMap args = new HashMap(); + args.put("padID", padId); + args.put("rev", new Integer(rev)); + return this.connection.get("getHTML", args); + } + + /** + * Creates a new revision with the given html (or creates a new pad). + * + * @param padId the pad's id string + * @param html the pad's new html text + */ + public void setHTML(String padId, String html) { + HashMap args = new HashMap(); + args.put("padID", padId); + args.put("html", html); + this.connection.post("setHTML", args); + } + + // Pads + // Group pads are normal pads, but with the name schema GROUPID$PADNAME. A security manager controls access of them and its + // forbidden for normal pads to include a $ in the name. + + /** + * Create a new pad. + * + * @param padId the pad's id string + */ + public void createPad(String padId) { + HashMap args = new HashMap(); + args.put("padID", padId); + this.connection.post("createPad", args); + } + + /** + * Create a new pad with the given initial text. + * + * @param padId the pad's id string + * @param text the initial text string + */ + public void createPad(String padId, String text) { + HashMap args = new HashMap(); + args.put("padID", padId); + args.put("text", text); + this.connection.post("createPad", args); + } + + /** + * Returns the number of revisions of this pad. The number is in "revisions". + * + * @param padId the pad's id string + * @return HashMap + */ + public HashMap getRevisionsCount(String padId) { + HashMap args = new HashMap(); + args.put("padID", padId); + return this.connection.get("getRevisionsCount", args); + } + + /** + * List the ids of authors who have edited a pad. They will be in an array inside "authorIDs". + * + * @param padId the pad's id string + * @return HashMap + */ + public HashMap listAuthorsOfPad(String padId) { + HashMap args = new HashMap(); + args.put("padID", padId); + return this.connection.get("listAuthorsOfPad", args); + } + + /** + * Deletes a pad. + * + * @param padId the pad's id string + */ + public void deletePad(String padId) { + HashMap args = new HashMap(); + args.put("padID", padId); + this.connection.post("deletePad", args); + } + + /** + * Get the pad's read-only id. The id will be in "readOnlyID". + * + * @param padId the pad's id string + * @return HashMap + */ + public HashMap getReadOnlyID(String padId) { + HashMap args = new HashMap(); + args.put("padID", padId); + return this.connection.get("getReadOnlyID", args); + } + + /** + * Get the pad's last edit date as a Unix timestamp. The timestamp will be in "lastEdited". + * + * @param padId the pad's id string + * @return HashMap + */ + public HashMap getLastEdited(String padId) { + HashMap args = new HashMap(); + args.put("padID", padId); + return this.connection.get("getLastEdited", args); + } + + /** + * Get the number of users currently editing a pad. + * + * @param padId the pad's id string + * @return Long + */ + public Long padUsersCount(String padId) { + HashMap args = new HashMap(); + args.put("padID", padId); + Long userCount = (Long) this.connection.get("padUsersCount", args).get("padUsersCount"); + return userCount; + } + + /** + * Returns the list of users that are currently editing this pad. + * A padUser has the values: "colorId", "name" and "timestamp". + * + * @param padId + * @return HashMap + */ + public HashMap padUsers(String padId) { + HashMap args = new HashMap(); + args.put("padID", padId); + return this.connection.get("padUsers", args); + } + + /** + * Sets the pad's public status. + * This is only applicable to group pads. + * + * @param padId the pad's id string + * @param publicStatus boolean + */ + public void setPublicStatus(String padId, Boolean publicStatus) { + HashMap args = new HashMap(); + args.put("padID", padId); + args.put("publicStatus", publicStatus); + this.connection.post("setPublicStatus", args); + } + + /** + * Gets the pad's public status. The boolean is in "publicStatus". + * This is only applicable to group pads.
+ *
+ * Example:
+ *
+ * + * Boolean is_public = (Boolean)api.getPublicStatus("g.kjsdfj7ask$foo").get("publicStatus"); + * + * + * @param padId the pad's id string + * @return HashMap + */ + public HashMap getPublicStatus(String padId) { + HashMap args = new HashMap(); + args.put("padID", padId); + return this.connection.get("getPublicStatus", args); + } + + /** + * Sets the pad's password. This is only applicable to group pads. + * + * @param padId the pad's id string + * @param password string + */ + public void setPassword(String padId, String password) { + HashMap args = new HashMap(); + args.put("padID", padId); + args.put("password", password); + this.connection.post("setPassword", args); + } + + /** + * Checks whether the pad is password-protected or not. The boolean is in "isPasswordProtected". + * This is only applicable to group pads.
+ *
+ * Example:
+ *
+ * + * Boolean pass = (Boolean)api.isPasswordProtected("g.kjsdfj7ask$foo").get("isPasswordProtected"); + * + * + * @param padId the pad's id string + * @return HashMap + */ + public HashMap isPasswordProtected(String padId) { + HashMap args = new HashMap(); + args.put("padID", padId); + return this.connection.get("isPasswordProtected", args); + } + + /** + * Sends a custom message of type msg to the pad. + * + * @param padId + * @param msg + */ + public void sendClientsMessage(String padId, String msg) { + HashMap args = new HashMap(); + args.put("padID", padId); + args.put("msg", msg); + this.connection.post("sendClientsMessage", args); + } + + /** + * Returns true if the connection is using SSL/TLS, false if not. + * + * @return boolean + */ + public boolean isSecure() { + if (this.connection.uri.getPort() == 443) { + return true; + } else { + return false; + } + } +} diff --git a/src/org/etherpad_lite_client/EPLiteConnection.java b/src/org/etherpad_lite_client/EPLiteConnection.java new file mode 100644 index 0000000..b6981ae --- /dev/null +++ b/src/org/etherpad_lite_client/EPLiteConnection.java @@ -0,0 +1,259 @@ +package org.etherpad_lite_client; + +import java.io.UnsupportedEncodingException; +import java.net.URI; +import java.net.URL; +import java.net.URLEncoder; +import java.util.Map; +import java.util.HashMap; +import java.util.Iterator; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; +import com.netsyms.symat.padview.Debug; + +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; + +/** + * Connection object for talking to and parsing responses from the Etherpad Lite + * Server. + */ +public class EPLiteConnection { + + public static final int CODE_OK = 0; + public static final int CODE_INVALID_PARAMETERS = 1; + public static final int CODE_INTERNAL_ERROR = 2; + public static final int CODE_INVALID_METHOD = 3; + public static final int CODE_INVALID_API_KEY = 4; + + /** + * The url of the API + */ + public URI uri; + + /** + * The API key + */ + public String apiKey; + + /** + * The Etherpad Lite API version + */ + public String apiVersion; + + /** + * Initializes a new org.etherpad_lite_client.EPLiteConnection object. + * + * @param url an absolute url, including protocol, to the EPL api + * @param apiKey the API Key + * @param apiVersion the API version + */ + public EPLiteConnection(String url, String apiKey, String apiVersion) { + this.uri = URI.create(url); + this.apiKey = apiKey; + this.apiVersion = apiVersion; + } + + /** + * GETs from the HTTP JSON API. + * + * @param apiMethod the name of the API method to call + * @return HashMap + */ + public HashMap get(String apiMethod) { + return this.get(apiMethod, new HashMap()); + } + + /** + * GETs from the HTTP JSON API. + * + * @param apiMethod the name of the API method to call + * @param apiArgs a HashMap of url/form parameters. apikey will be set + * automatically + * @return HashMap + */ + public HashMap get(String apiMethod, HashMap apiArgs) { + String path = this.apiPath(apiMethod); + String query = this.queryString(apiArgs); + URL url = apiUrl(path, query); + Request request = new GETRequest(url); + return this.call(request); + } + + /** + * POSTs to the HTTP JSON API. + * + * @param apiMethod the name of the API method to call + * @return HashMap + */ + public HashMap post(String apiMethod) { + return this.post(apiMethod, new HashMap()); + } + + /** + * POSTs to the HTTP JSON API. + * + * @param apiMethod the name of the API method to call + * @param apiArgs a HashMap of url/form parameters. apikey will be set + * automatically + * @return HashMap + */ + public HashMap post(String apiMethod, HashMap apiArgs) { + String path = this.apiPath(apiMethod); + String query = this.queryString(apiArgs); + URL url = apiUrl(path, null); + Request request = new POSTRequest(url, query); + return this.call(request); + } + + /** + * Calls the HTTP JSON API. + * + * @param request the request object to send + * @return HashMap + */ + private HashMap call(Request request) { + trustServerAndCertificate(); + + try { + String response = request.send(); + return this.handleResponse(response); + } catch (EPLiteException e) { + throw new EPLiteException(e.getMessage()); + } catch (Exception e) { + throw new EPLiteException("Unable to connect to SyMAT: " + e.getMessage()); + } + } + + /** + * Converts the API resonse's JSON string into a HashMap. + * + * @param jsonString a valid JSON string + * @return HashMap + */ + private HashMap handleResponse(String jsonString) { + try { + JSONParser parser = new JSONParser(); + Map response = (Map) parser.parse(jsonString); + // Act on the response code + if (!response.get("code").equals(null)) { + int code = ((Long) response.get("code")).intValue(); + switch (code) { + // Valid code, parse the response + case CODE_OK: + HashMap data = (HashMap) response.get("data"); + return data != null ? data : new HashMap(); + // Invalid code, throw an exception with the message + case CODE_INVALID_PARAMETERS: + case CODE_INVALID_API_KEY: + case CODE_INVALID_METHOD: + throw new EPLiteException((String) response.get("message")); + default: + throw new EPLiteException("An unknown error has occurred while handling the response: " + jsonString); + } + // No response code, something's really wrong + } else { + throw new EPLiteException("An unknown error has occurred while handling the response: " + jsonString); + } + } catch (ParseException e) { + System.err.println("Unable to parse JSON response (" + jsonString + "): " + e.getMessage()); + return new HashMap(); + } + } + + /** + * Returns the URL for the api path and query. + * + * @param path the api path + * @param query the query string (may be null) + * @return URL + */ + private URL apiUrl(String path, String query) { + try { + URL url = new URL(new URI(this.uri.getScheme(), null, this.uri.getHost(), this.uri.getPort(), path, query, null).toString()); + return url; + } catch (Exception e) { + throw new EPLiteException("Unable to connect to SyMAT: " + e.getMessage()); + } + } + + /** + * Returns a URI path for the API method + * + * @param apiMethod the api method + * @return String + */ + private String apiPath(String apiMethod) { + return this.uri.getPath() + "/api/" + this.apiVersion + "/" + apiMethod; + } + + /** + * Returns a query string made from HashMap keys and values + * + * @param apiArgs the api arguments in a HashMap + * @return String + */ + private String queryString(HashMap apiArgs) { + String strArgs = ""; + apiArgs.put("apikey", this.apiKey); + Iterator i = apiArgs.entrySet().iterator(); + while (i.hasNext()) { + Map.Entry e = (Map.Entry) i.next(); + Object value = e.getValue(); + if (value != null) { + try { + strArgs += e.getKey() + "=" + URLEncoder.encode(value.toString(), "utf-8"); + } catch (UnsupportedEncodingException ex) { + Debug.stacktrace(ex); + } + if (i.hasNext()) { + strArgs += "&"; + } + } + } + return strArgs; + } + + /** + * Creates a trust manager to trust all certificates if you open a ssl + * connection + */ + private void trustServerAndCertificate() { + // Create a trust manager that does not validate certificate chains + TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() { + public java.security.cert.X509Certificate[] getAcceptedIssuers() { + return null; + } + + public void checkClientTrusted( + java.security.cert.X509Certificate[] certs, String authType) { + } + + public void checkServerTrusted( + java.security.cert.X509Certificate[] certs, String authType) { + } + } + }; + + // Install the all-trusting trust manager + try { + SSLContext sc = SSLContext.getInstance("SSL"); + sc.init(null, trustAllCerts, new java.security.SecureRandom()); + HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); + } catch (Exception e) { + } + + HostnameVerifier hv = new HostnameVerifier() { + //@Override + public boolean verify(String hostname, SSLSession session) { + return true; + } + }; + HttpsURLConnection.setDefaultHostnameVerifier(hv); + } +} diff --git a/src/org/etherpad_lite_client/EPLiteException.java b/src/org/etherpad_lite_client/EPLiteException.java new file mode 100644 index 0000000..773af32 --- /dev/null +++ b/src/org/etherpad_lite_client/EPLiteException.java @@ -0,0 +1,7 @@ +package org.etherpad_lite_client; + +public class EPLiteException extends RuntimeException { + public EPLiteException(String msg) { + super(msg); + } +} diff --git a/src/org/etherpad_lite_client/GETRequest.java b/src/org/etherpad_lite_client/GETRequest.java new file mode 100644 index 0000000..c9186d3 --- /dev/null +++ b/src/org/etherpad_lite_client/GETRequest.java @@ -0,0 +1,47 @@ +package org.etherpad_lite_client; + +import java.net.URL; +import java.io.BufferedReader; +import java.io.InputStreamReader; + +/** + * A class for easily executing an HTTP GET request.
+ *
+ * Example:
+ *
+ * + * Request req = new GETRequest(url_object);
+ * String resp = req.send();
+ *
+ */ +public class GETRequest implements Request { + /** + * The URL object. + */ + private URL url; + + /** + * Instantiates a new GETRequest. + * + * @param url the URL object + */ + public GETRequest(URL url) { + this.url = url; + } + + /** + * Sends the request and returns the response. + * + * @return String + */ + public String send() throws Exception { + BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream())); + String response = ""; + String buffer; + while ((buffer = in.readLine()) != null) { + response += buffer; + } + in.close(); + return response; + } +} diff --git a/src/org/etherpad_lite_client/POSTRequest.java b/src/org/etherpad_lite_client/POSTRequest.java new file mode 100644 index 0000000..bf8d619 --- /dev/null +++ b/src/org/etherpad_lite_client/POSTRequest.java @@ -0,0 +1,59 @@ +package org.etherpad_lite_client; + +import java.net.URL; +import java.net.URLConnection; +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; + +/** + * A class for easily executing an HTTP POST request.
+ *
+ * Example:
+ *
+ * + * Request req = new POSTRequest(url_object);
+ * String resp = req.send();
+ *
+ */ +public class POSTRequest implements Request { + /** + * The URL object. + */ + private URL url; + + /** + * Instantiates a new POSTRequest. + * + * @param url the URL object + */ + private String args; + + public POSTRequest(URL url, String args) { + this.url = url; + this.args = args; + } + + /** + * Sends the request and returns the response. + * + * @return String + */ + public String send() throws Exception { + URLConnection con = this.url.openConnection(); + con.setDoOutput(true); + + OutputStreamWriter out = new OutputStreamWriter(con.getOutputStream()); + out.write(this.args); + out.close(); + + BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); + String response = ""; + String buffer; + while ((buffer = in.readLine()) != null) { + response += buffer; + } + in.close(); + return response; + } +} diff --git a/src/org/etherpad_lite_client/Request.java b/src/org/etherpad_lite_client/Request.java new file mode 100644 index 0000000..add1941 --- /dev/null +++ b/src/org/etherpad_lite_client/Request.java @@ -0,0 +1,9 @@ +package org.etherpad_lite_client; + +import java.net.URL; + +public interface Request { + URL url = null; + + public abstract String send() throws Exception; +}