[libbrowserlauncher-java] 01/07: Imported Upstream version 1.3+dfsg
Andreas Tille
tille at debian.org
Mon Jan 18 12:12:32 UTC 2016
This is an automated email from the git hooks/post-receive script.
tille pushed a commit to branch master
in repository libbrowserlauncher-java.
commit 7187c71699e118e0bc2ba784a64f057b3d639fc4
Author: Andreas Tille <tille at debian.org>
Date: Mon Jan 18 10:54:02 2016 +0100
Imported Upstream version 1.3+dfsg
---
.classpath | 6 +
.project | 17 +
COPYING.txt | 458 +++++++++++
META-INF/INDEX.LIST | 56 ++
META-INF/MANIFEST.MF | 5 +
README.txt | 85 ++
build.xml | 81 ++
.../ejalbert/browserprefui/BrowserPrefs.properties | 26 +
.../launching/misc/linuxUnixConfig.properties | 33 +
.../ejalbert/launching/misc/sunOSConfig.properties | 32 +
.../launching/windows/windowsConfig.properties | 48 ++
.../ejalbert/resources/Debugging.properties | 59 ++
source/at/jta/NotSupportedOSException.java | 28 +
source/at/jta/RegistryErrorException.java | 31 +
source/at/jta/Regor.java | 741 ++++++++++++++++++
source/edu/stanford/ejalbert/BrowserLauncher.java | 407 ++++++++++
.../stanford/ejalbert/BrowserLauncherRunner.java | 144 ++++
.../ejalbert/browserprefui/BrowserPrefAction.java | 104 +++
.../ejalbert/browserprefui/BrowserPrefDialog.java | 130 ++++
.../ejalbert/browserprefui/BrowserPrefs.properties | 26 +
.../BrowserLaunchingExecutionException.java | 40 +
.../BrowserLaunchingInitializingException.java | 39 +
.../UnsupportedOperatingSystemException.java | 40 +
.../BrowserLauncherDefaultErrorHandler.java | 44 ++
.../BrowserLauncherErrorHandler.java | 41 +
.../ejalbert/launching/BrowserDescription.java | 45 ++
.../launching/BrowserLaunchingFactory.java | 127 +++
.../ejalbert/launching/IBrowserLaunching.java | 177 +++++
.../launching/macos/MacOs2_0BrowserLaunching.java | 153 ++++
.../launching/macos/MacOs2_1BrowserLaunching.java | 144 ++++
.../launching/macos/MacOs3_0BrowserLaunching.java | 110 +++
.../launching/macos/MacOs3_1BrowserLaunching.java | 76 ++
.../launching/macos/MacOsBrowserLaunching.java | 113 +++
.../launching/misc/StandardUnixBrowser.java | 202 +++++
.../launching/misc/SunOSBrowserLaunching.java | 98 +++
.../ejalbert/launching/misc/UnixBrowser.java | 61 ++
.../misc/UnixNetscapeBrowserLaunching.java | 375 +++++++++
.../launching/misc/linuxUnixConfig.properties | 33 +
.../ejalbert/launching/misc/sunOSConfig.properties | 32 +
.../ejalbert/launching/utils/LaunchingUtils.java | 55 ++
.../ejalbert/launching/windows/WindowsBrowser.java | 147 ++++
.../launching/windows/WindowsBrowserLaunching.java | 857 +++++++++++++++++++++
.../launching/windows/windowsConfig.properties | 48 ++
.../ejalbert/resources/Debugging.properties | 59 ++
.../ejalbert/testing/BrowserLauncherTestApp.java | 349 +++++++++
.../stanford/ejalbert/testing/TestAppLogger.java | 107 +++
source/net/sf/wraplog/AbstractLogger.java | 167 ++++
source/net/sf/wraplog/Level.java | 76 ++
source/net/sf/wraplog/Logger.java | 70 ++
source/net/sf/wraplog/LoggingException.java | 46 ++
source/net/sf/wraplog/NoneLogger.java | 52 ++
source/net/sf/wraplog/SystemLogger.java | 101 +++
52 files changed, 6601 insertions(+)
diff --git a/.classpath b/.classpath
new file mode 100644
index 0000000..6a7b37f
--- /dev/null
+++ b/.classpath
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="source"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="output" path="classes"/>
+</classpath>
diff --git a/.project b/.project
new file mode 100644
index 0000000..0a929c6
--- /dev/null
+++ b/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>BrowserLauncher2</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/COPYING.txt b/COPYING.txt
new file mode 100644
index 0000000..3b20440
--- /dev/null
+++ b/COPYING.txt
@@ -0,0 +1,458 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
diff --git a/META-INF/INDEX.LIST b/META-INF/INDEX.LIST
new file mode 100644
index 0000000..24c51b5
--- /dev/null
+++ b/META-INF/INDEX.LIST
@@ -0,0 +1,56 @@
+JarIndex-Version: 1.0
+
+BrowserLauncher2-all-1_3.jar
+at
+at/jta
+classes
+classes/edu
+classes/edu/stanford
+classes/edu/stanford/ejalbert
+classes/edu/stanford/ejalbert/browserprefui
+classes/edu/stanford/ejalbert/launching
+classes/edu/stanford/ejalbert/launching/misc
+classes/edu/stanford/ejalbert/launching/windows
+classes/edu/stanford/ejalbert/resources
+edu
+edu/stanford
+edu/stanford/ejalbert
+edu/stanford/ejalbert/browserprefui
+edu/stanford/ejalbert/exception
+edu/stanford/ejalbert/exceptionhandler
+edu/stanford/ejalbert/launching
+edu/stanford/ejalbert/launching/macos
+edu/stanford/ejalbert/launching/misc
+edu/stanford/ejalbert/launching/utils
+edu/stanford/ejalbert/launching/windows
+edu/stanford/ejalbert/resources
+edu/stanford/ejalbert/testing
+net
+net/sf
+net/sf/wraplog
+package cache
+source
+source/at
+source/at/jta
+source/edu
+source/edu/stanford
+source/edu/stanford/ejalbert
+source/edu/stanford/ejalbert/browserprefui
+source/edu/stanford/ejalbert/exception
+source/edu/stanford/ejalbert/exceptionhandler
+source/edu/stanford/ejalbert/launching
+source/edu/stanford/ejalbert/launching/macos
+source/edu/stanford/ejalbert/launching/misc
+source/edu/stanford/ejalbert/launching/utils
+source/edu/stanford/ejalbert/launching/windows
+source/edu/stanford/ejalbert/resources
+source/edu/stanford/ejalbert/testing
+source/net
+source/net/sf
+source/net/sf/wraplog
+.classpath
+.project
+COPYING.txt
+README.txt
+build.xml
+
diff --git a/META-INF/MANIFEST.MF b/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..959ed9c
--- /dev/null
+++ b/META-INF/MANIFEST.MF
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+Ant-Version: Apache Ant 1.6.5
+Created-By: 1.4.2_04-b05 (Sun Microsystems Inc.)
+Main-Class: edu/stanford/ejalbert/testing/BrowserLauncherTestApp
+
diff --git a/README.txt b/README.txt
new file mode 100644
index 0000000..8326cb6
--- /dev/null
+++ b/README.txt
@@ -0,0 +1,85 @@
+$Id: README.txt,v 1.4 2007/08/30 19:44:04 jchapman0 Exp $
+
+Introduction
+------------
+
+BrowserLauncher2, a continuation of the BrowserLauncher project,
+is a library that facilitates openning a browser from a Java
+application and directing the browser to a supplied url. In
+most cases the browser openned will be the user's default browser.
+
+BrowserLauncher2 has been released under the LGPL.
+Read the COPYING.txt file for licensing information.
+
+Project Founder (BrowserLauncher):
+Eric Albert
+
+Project Founder (BrowserLauncher2):
+Jeff Chapman sdvalidator at yahoo.com
+
+Contributors:
+Thomas Aglassinger
+Jeff Chapman
+Chris Dance
+Markus Gebhard
+Olivier Hochreutiner
+Morgan Schweers
+
+This software is OSI Certified Open Source Software.
+OSI Certified is a certification mark of the Open Source Initiative.
+For more information on OSI, see http://www.opensource.org
+
+System Requirements
+-------------------
+
+BrowserLauncher2 is written entirely in Java. The libraries have been
+compiled using JDK 1.4. Operating System support is ongoing. The library
+supports various flavors of Mac, Windows, and Unix/Linux.
+
+Using the Library
+-----------------
+
+The preferred method for using the BrowserLauncher2 api is to create an
+instance of BrowserLauncher (edu.stanford.ejalbert.BrowserLauncher) and
+invoke the method: public void openURLinBrowser(String urlString).
+
+If the application will be invoking urls often, it might be useful to wrap
+the BrowserLauncher instance with a singleton or use some mechanism to cache it.
+
+The call to openURLinBrowser() should be executed in a separate thread from
+the application's main/event thread. Applications can create an instance of
+BrowserLauncherRunner (edu.stanford.ejalbert.BrowserLauncherRunner) and pass
+it to a Thread. The sample code below is taken from the test application
+(edu.stanford.ejalbert.BrowserLauncher.BrowserLauncherTestApp) which can be
+used as a reference application.
+
+BrowserLauncherErrorHandler errorHandler = new TestAppErrorHandler(debugTextArea);
+BrowserLauncherRunner runner = new BrowserLauncherRunner(launcher, urlString, errorHandler);
+Thread launcherThread = new Thread(runner);
+launcherThread.start();
+
+Third Party Libraries:
+
+BrowserLauncher2 uses two libraries: WrapLog and Pure Java registry wrapper for Windows.
+The code for these libraries is integrated into the BrowserLauncher2 build.
+
+Logging
+---------
+BrowserLauncher2 uses a subset of WrapLog 1.1 for logging. If you do not specify a logger
+instance, a default logger (NoneLogger) will be used. The default logger does not log
+anything.
+
+WrapLog is available under the BSD License.
+
+For more information on using WrapLog, see http://sourceforge.net/projects/wraplog.
+
+Windows Registry Access
+-----------------------
+BrowserLauncher2 uses Pure Java registry wrapper for Windows (release/version 2.0) for
+reading the Windows registry to locate browsers on a user's system.
+
+Pure Java registry wrapper for Windows is available under the GNU Library or Lesser
+General Public License (LGPL).
+
+For more information on using Pure Java registry wrapper for Windows, see
+http://sourceforge.net/projects/java-registry.
diff --git a/build.xml b/build.xml
new file mode 100644
index 0000000..0bbf084
--- /dev/null
+++ b/build.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0"?>
+<!-- Build file for BrowserLauncher2 -->
+<!-- $Id: build.xml,v 1.9 2007/08/30 19:47:37 jchapman0 Exp $ -->
+<project name="BrowserLauncher2" default="build" basedir=".">
+ <property name="release.number" value="1_3" /> <!-- 1.3 -->
+ <property name="product.name" value="BrowserLauncher2" />
+ <property name="output.dir" value="classes" />
+ <property name="source.dir" value="source" />
+ <property name="lib.dir" value="lib" />
+ <property name="deployment.dir" value="deployment" />
+ <property name="api.dir" value="api" />
+ <property name="archive.runtime" value="${deployment.dir}/BrowserLauncher2-${release.number}.jar" />
+ <property name="archive.all" value="${deployment.dir}/BrowserLauncher2-all-${release.number}.jar" />
+ <property name="optimize" value="on" />
+ <property name="app.manifest" value="${deployment.dir}/manifest.mf" />
+ <property name="app.manifest.test" value="${deployment.dir}/manifest.test.mf" />
+ <property name="gnu.copying" value="${deployment.dir}/COPYING.txt" />
+ <property name="readme" location="${deployment.dir}/README.txt" />
+
+ <target name="init">
+ <tstamp />
+ <mkdir dir="${lib.dir}" />
+ <mkdir dir="${output.dir}" />
+ <mkdir dir="${deployment.dir}" />
+ </target>
+
+ <target name="clean-deploy" description="does clean then deploy">
+ <antcall target="clean"/>
+ <antcall target="deploy"/>
+ </target>
+
+ <target name="clean" description="remove all files created by build" depends="init">
+ <delete>
+ <fileset dir="${output.dir}" />
+ </delete>
+ <delete dir="${api.dir}" />
+ <delete file="${archive.all}" />
+ <delete file="${archive.runtime}" />
+ </target>
+
+ <target name="build" depends="init" description="compile all source files">
+ <mkdir dir="${output.dir}" />
+ <javac srcdir="${source.dir}" destdir="${output.dir}" debug="true" />
+ <!-- copy all non-java files (properties) -->
+ <copy todir="${output.dir}">
+ <fileset dir="${source.dir}" excludes="**/*.java"/>
+ </copy>
+ <jar destfile="${archive.runtime}" basedir="${output.dir}" includes="**/*.class" />
+ </target>
+
+ <target name="deploy" depends="build" description="create archives">
+ <jar destfile="${archive.runtime}"
+ index="true"
+ update="overwrite"
+ manifest="${app.manifest}" >
+ <fileset dir="${output.dir}" />
+ <fileset file="${gnu.copying}" />
+ <fileset file="${readme}" />
+ </jar>
+ <jar destfile="${archive.all}"
+ index="true"
+ update="overwrite"
+ manifest="${app.manifest.test}" >
+ <fileset dir="${output.dir}" />
+ <fileset dir="." includes="build.xml, *.txt" />
+ <fileset dir="." includes=".classpath, .project" />
+ <fileset dir="." includes="**/*.java" />
+ <fileset dir="." includes="**/*.properties" />
+ <fileset dir="." includes="${api.dir}/**" />
+ <fileset file="${gnu.copying}" />
+ <fileset file="${readme}" />
+ </jar>
+ </target>
+
+ <target name="api" depends="init" description="create API documentation">
+ <javadoc destdir="${api.dir}" windowtitle="${product.name}" link="http://java.sun.com/j2se/1.4.2/docs/api/" author="true" version="true" package="true">
+ <packageset dir="${source.dir}" />
+ </javadoc>
+ </target>
+
+</project>
diff --git a/edu/stanford/ejalbert/browserprefui/BrowserPrefs.properties b/edu/stanford/ejalbert/browserprefui/BrowserPrefs.properties
new file mode 100644
index 0000000..8a9bf91
--- /dev/null
+++ b/edu/stanford/ejalbert/browserprefui/BrowserPrefs.properties
@@ -0,0 +1,26 @@
+# ************************************************
+# Copyright 2006 Jeff Chapman
+
+# This file is part of BrowserLauncher2.
+
+# BrowserLauncher2 is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+# BrowserLauncher2 is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public License
+# along with BrowserLauncher2; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+# ************************************************/
+# $Id: BrowserPrefs.properties,v 1.1 2006/09/26 19:40:41 jchapman0 Exp $
+
+dialog.title=Browser Preference
+
+dialog.bttn.ok=OK
+dialog.bttn.cancel=Cancel
diff --git a/edu/stanford/ejalbert/launching/misc/linuxUnixConfig.properties b/edu/stanford/ejalbert/launching/misc/linuxUnixConfig.properties
new file mode 100644
index 0000000..ff858fb
--- /dev/null
+++ b/edu/stanford/ejalbert/launching/misc/linuxUnixConfig.properties
@@ -0,0 +1,33 @@
+# ************************************************
+# Copyright 2006,2007 Jeff Chapman
+#
+# This file is part of BrowserLauncher2.
+#
+# BrowserLauncher2 is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# BrowserLauncher2 is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with BrowserLauncher2; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+# ************************************************
+# $Id: linuxUnixConfig.properties,v 1.3 2007/06/13 19:25:54 jchapman0 Exp $
+
+# delimiter for browser listing
+delimchar=;
+
+# list of browsers and arguments for using them
+# display name | executable name | start browser args | invoke already started browser | force new window
+browser.mozilla=Mozilla;mozilla;<browser> <url>;<browser> -remote openURL(<url>)
+browser.netscape=Netscape;netscape;<browser> <url>;<browser> -remote openURL(<url>)
+browser.firefox=FireFox;firefox;<browser> <url>;<browser> -new-tab <url>;<browser> -new-window <url>
+browser.mozilla-firefox=FireFox;mozilla-firefox;<browser> <url>;<browser> -remote openURL(<url>);<browser> -new-window <url>
+browser.konqueror=Konqueror;kfmclient;<browser> openURL <url>;<browser> newTab <url>;<browser> openURL <url>
+browser.opera=Opera;opera;<browser> <url>;<browser> -newpage <url>;<browser> -newwindow <url>
+browser.epiphany=Epiphany;epiphany;<browser> <url>;<browser> --new-tab <url>
diff --git a/edu/stanford/ejalbert/launching/misc/sunOSConfig.properties b/edu/stanford/ejalbert/launching/misc/sunOSConfig.properties
new file mode 100644
index 0000000..af32b42
--- /dev/null
+++ b/edu/stanford/ejalbert/launching/misc/sunOSConfig.properties
@@ -0,0 +1,32 @@
+# ************************************************
+# Copyright 2006 Jeff Chapman
+#
+# This file is part of BrowserLauncher2.
+#
+# BrowserLauncher2 is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# BrowserLauncher2 is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with BrowserLauncher2; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+# ************************************************
+# $Id: sunOSConfig.properties,v 1.2 2006/09/12 15:40:34 jchapman0 Exp $
+
+# delimiter for browser listing
+delimchar=;
+
+# list of browsers and arguments for using them
+# display name | executable name | start browser args | invoke already started browser
+browser.sdtwebclient=Default;sdtwebclient;<browser> <url>;<browser> -remote openURL(<url>)
+browser.mozilla=Mozilla;mozilla;<browser> <url>;<browser> -remote openURL(<url>)
+browser.netscape=Netscape;netscape;<browser> <url>;<browser> -remote openURL(<url>)
+browser.firefox=FireFox;firefox;<browser> <url>;<browser> -remote openURL(<url>);<browser> -new-window <url>
+browser.opera=Opera;opera;<browser> <url>;<browser> -newpage <url>;<browser> -newwindow <url>
+
diff --git a/edu/stanford/ejalbert/launching/windows/windowsConfig.properties b/edu/stanford/ejalbert/launching/windows/windowsConfig.properties
new file mode 100644
index 0000000..abdcd2e
--- /dev/null
+++ b/edu/stanford/ejalbert/launching/windows/windowsConfig.properties
@@ -0,0 +1,48 @@
+# ************************************************
+# Copyright 2006,2007 Jeff Chapman
+#
+# This file is part of BrowserLauncher2.
+#
+# BrowserLauncher2 is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# BrowserLauncher2 is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with BrowserLauncher2; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+# ************************************************
+# $Id: windowsConfig.properties,v 1.6 2007/08/30 19:38:09 jchapman0 Exp $
+
+# delimiter for browser listing
+delimchar=;
+
+# windows versions and arguments for launching a browser
+# command for starting default browser | command for starting a specific browser | use registry
+windows.winVista=cmd.exe /c start "" "<url>";"<path><browser>.exe" <args> "<url>";true
+windows.win2000=cmd.exe /c start "" "<url>";"<path><browser>.exe" <args> "<url>";true
+windows.win9x=command.com /c start "<url>";"<path><browser>.exe" <args> "<url>";true
+windows.winNT=cmd.exe /c start "" "<url>";"<path><browser>.exe" <args> "<url>";true
+
+# properties used to find browsers in program files folder
+program.files.template={0}:\\Program Files
+# drive letters to try when looking for Program Files folder
+drive.letters=C;D;E
+
+#windows.win2000=cmd.exe /c start "" "<url>";cmd.exe /c start <browser> <args> "<url>"
+#windows.win9x=command.com /c start "<url>";command.com /c start <browser> <args> "<url>"
+#windows.winNT=cmd.exe /c start "" "<url>";cmd.exe /c start <browser> <args> "<url>"
+
+# list of browsers and arguments for using them and discovering them
+# browser display name | browser exe name | new window argument | directory containing exe
+browser.mozilla=Mozilla;mozilla;;mozilla.org
+browser.netscape=Netscape;netscape;;Netscape
+browser.firefox=FireFox;firefox;-new-window;Mozilla Firefox
+browser.opera=Opera;opera;-newwindow;Opera
+browser.ie=IE;iexplore;;Internet Explorer
+browser.kmeleon=K-Meleon;k-meleon;;K-Meleon
diff --git a/edu/stanford/ejalbert/resources/Debugging.properties b/edu/stanford/ejalbert/resources/Debugging.properties
new file mode 100644
index 0000000..c80e945
--- /dev/null
+++ b/edu/stanford/ejalbert/resources/Debugging.properties
@@ -0,0 +1,59 @@
+# ************************************************
+# Copyright 2005 Jeff Chapman
+
+# This file is part of BrowserLauncher2.
+
+# BrowserLauncher2 is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+# BrowserLauncher2 is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public License
+# along with BrowserLauncher2; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+# ************************************************/
+# $Id: Debugging.properties,v 1.8 2007/01/31 18:31:22 jchapman0 Exp $
+
+# Resource file containing strings and other info for use by the Testing
+# tool.
+
+# initial message to display
+debug.mssg=\
+Please let us know the results of testing on your OS/Java configuration. The \
+information displayed below as well as any stack traces will be \
+helpful. Use the copy button to copy and paste the data into an email.
+
+# system properties to query and display, | and ; as separators
+# display|property.name;
+debug.propnames=\
+Java Version: |java.version;\
+Java Vendor: |java.vendor;\
+OS Name: |os.name;\
+OS Version: |os.version
+
+label.url=Enter a url:
+label.app.title=BrowserLauncher2 Test App 1.0
+label.logging.level=Logging Level:
+label.browser.list=Browser List:
+label.window.policy=Force New Window
+
+bttn.browse=Browse
+bttn.copy=Copy
+bttn.set.logging=Set Logging Level
+bttn.set.preference=Set Browser Preference
+
+logging.level.select.title=Logging Level Selection
+logging.level.select.message=Select a logging level from the list below
+
+url.default=file://localhost/
+
+# properties for logging interface
+logging.dateformat=yyyy-MM-dd HH:mm:ss,SSS
+
+logging.level.labels=DEBUG;INFO;WARN;ERROR
diff --git a/source/at/jta/NotSupportedOSException.java b/source/at/jta/NotSupportedOSException.java
new file mode 100644
index 0000000..a82b57b
--- /dev/null
+++ b/source/at/jta/NotSupportedOSException.java
@@ -0,0 +1,28 @@
+// $Id: NotSupportedOSException.java,v 1.1 2007/08/30 19:40:24 jchapman0 Exp $
+package at.jta;
+
+/********************************************************************************************************************************
+ *
+ * <p>Title: Exception is thrown if you use the regor class on not windows machines </p>
+ *
+ * <p>Description: </p>
+ *
+ * <p>Copyright: Copyright (c) 2007</p>
+ *
+ * <p>Company: Taschek Joerg</p>
+ *
+ * @author Taschek Joerg
+ * @version 1.0
+ *******************************************************************************************************************************/
+public class NotSupportedOSException
+ extends RuntimeException
+{
+ /******************************************************************************************************************************
+ * Constructor with message to throw
+ * @param str String
+ *****************************************************************************************************************************/
+ public NotSupportedOSException(String str)
+ {
+ super(str);
+ }
+}
diff --git a/source/at/jta/RegistryErrorException.java b/source/at/jta/RegistryErrorException.java
new file mode 100644
index 0000000..1760c73
--- /dev/null
+++ b/source/at/jta/RegistryErrorException.java
@@ -0,0 +1,31 @@
+// $Id: RegistryErrorException.java,v 1.1 2007/08/30 19:40:24 jchapman0 Exp $
+package at.jta;
+
+import java.io.IOException;
+
+/*******************************************************************************************************************************
+ *
+ * <p>Title: class for throwing exceptions </p>
+ *
+ * <p>Description: </p>
+ *
+ * <p>Copyright: Copyright (c) 2007</p>
+ *
+ * <p>Company: Taschek Joerg</p>
+ *
+ * @author Taschek Joerg
+ * @version 1.0
+ ******************************************************************************************************************************/
+public class RegistryErrorException
+ extends IOException
+{
+
+ /******************************************************************************************************************************
+ * Constructor with message to throw
+ * @param reason String
+ *****************************************************************************************************************************/
+ public RegistryErrorException(String reason)
+ {
+ super(reason);
+ }
+}
diff --git a/source/at/jta/Regor.java b/source/at/jta/Regor.java
new file mode 100644
index 0000000..94e75b4
--- /dev/null
+++ b/source/at/jta/Regor.java
@@ -0,0 +1,741 @@
+// $Id: Regor.java,v 1.1 2007/08/30 19:40:24 jchapman0 Exp $
+package at.jta;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+import java.util.List;
+import java.util.ArrayList;
+
+/********************************************************************************************************************************
+ *
+ * <p>Title: Class is 100% pur Java Registry handle (just can write/read string values)</p>
+ *
+ * <p>Description: You can read, delete or create any key in the registry (when you have access rights).
+ * But you just can read/delete and set string values! The java.dll doenst provide any other feature </p>
+ *
+ * <p>Copyright: Copyright (c) 2006</p>
+ *
+ * <p>Company: Taschek Joerg</p>
+ *
+ * @author Taschek Joerg
+ * @version 2.0 22.03.2007 Methods are renamed and now called by the function they are implementing and the document is now in
+ * english, instead of german
+ *******************************************************************************************************************************/
+final public class Regor
+{
+ /**
+ * the handle to the HKEY_CLASSES_ROOT registry root node
+ */
+ public static final int HKEY_CLASSES_ROOT = 0x80000000;
+ /**
+ * the handle to the HEKY_CURRENT_USER registry root node
+ */
+ public static final int HKEY_CURRENT_USER = 0x80000001;
+ /**
+ * the handle to the HKEY_LOCAL_MACHINE registry root node
+ */
+ public static final int HKEY_LOCAL_MACHINE = 0x80000002;
+
+
+ public static final int ERROR_SUCCESS = 0;
+ public static final int ERROR_FILE_NOT_FOUND = 2;
+ public static final int ERROR_ACCESS_DENIED = 5;
+
+ /* Constants used to interpret returns of native functions */
+ public static final int NATIVE_HANDLE = 0;
+ public static final int ERROR_CODE = 1;
+ public static final int SUBKEYS_NUMBER = 0;
+ public static final int VALUES_NUMBER = 2;
+ public static final int MAX_KEY_LENGTH = 3;
+ public static final int MAX_VALUE_NAME_LENGTH = 4;
+
+
+ /* Windows security masks */
+ /**
+ * Security Mask need by openKey - just for delete
+ */
+ public static final int DELETE = 0x10000;
+ /**
+ * Security Mask need by openKey - just for querying values
+ */
+ public static final int KEY_QUERY_VALUE = 1;
+ /**
+ * Security Mask need by openKey - just for setting values
+ */
+ public static final int KEY_SET_VALUE = 2;
+ /**
+ * Security Mask need by openKey - for creating sub keys
+ */
+ public static final int KEY_CREATE_SUB_KEY = 4;
+ /**
+ * Security Mask need by openKey - for enum sub keys
+ */
+ public static final int KEY_ENUMERATE_SUB_KEYS = 8;
+ /**
+ * Security Mask need by openKey - for key reading
+ */
+ public static final int KEY_READ = 0x20019;
+ /**
+ * Security Mask need by openKey - for writing keys
+ */
+ public static final int KEY_WRITE = 0x20006;
+ /**
+ * Security Mask need by openKey - highest access to do everything (default access by openkey without security mask)
+ */
+ public static final int KEY_ALL_ACCESS = 0xf003f;
+
+ private Method openKey = null;
+ private Method closeKey = null;
+ private Method delKey = null;
+ private Method createKey = null;
+ private Method flushKey = null;
+ private Method queryValue = null;
+ private Method setValue = null;
+ private Method delValue = null;
+ private Method queryInfoKey = null;
+ private Method enumKey = null;
+ private Method enumValue = null;
+
+ /******************************************************************************************************************************
+ * Constructor to handle with windows registry
+ * @throws RegistryErrorException throws an registryerrorException when its not able to get a handle to the registry methods
+ * @throws NotSupportedOSException throws an notSupportedOSException if the registry is not used in windows
+ *****************************************************************************************************************************/
+ public Regor() throws RegistryErrorException
+ {
+ checkOS();
+ initMethods();
+ }
+
+ /******************************************************************************************************************************
+ * Method checks either if its windows or anohter system (if not windows an exception is thrown) - just needed for internal checks
+ *****************************************************************************************************************************/
+ private void checkOS()
+ {
+ String str = System.getProperty("os.name");
+ if(str == null || str.toLowerCase().indexOf("windows") == -1)
+ throw new NotSupportedOSException("Operating system: " + str + " is not supported!");
+ }
+
+ /******************************************************************************************************************************
+ * Reading every valueName (not only the string value) out of the registry handle (for maximum value index and maxValueNameLength
+ * use the getChildInformation method
+ * @param key the handle to the parent key obtained from openKey
+ * @param valueNameIndex the index of the valueName name - starting from 0 going to the maximum count from the getChildInformation
+ * stored in array index 2
+ * @param maxValueNameLength maximum length of valueName name (used because for memory allocating in the java.dll - if you obtain
+ * the size from getChildInformation increase the [4] int array by 1)
+ * @return byte[] either the name of the valueName or null if not found or an error occurs or if the maxValueNameLength is to short
+ * @throws RegistryErrorException
+ *****************************************************************************************************************************/
+ public byte[] enumValueName(int key, int valueNameIndex, int maxValueNameLength) throws RegistryErrorException
+ {
+ try
+ {
+ return (byte[])enumValue.invoke(null, new Object[] {new Integer(key), new Integer(valueNameIndex), new Integer(maxValueNameLength)});
+ }
+ catch (InvocationTargetException ex)
+ {
+ throw new RegistryErrorException(ex.getMessage());
+ }
+ catch (IllegalArgumentException ex)
+ {
+ throw new RegistryErrorException(ex.getMessage());
+ }
+ catch (IllegalAccessException ex)
+ {
+ throw new RegistryErrorException(ex.getMessage());
+ }
+ }
+
+ /*****************************************************************************************************************************
+ * Returns every valueName (not only the String value names)
+ * @param key either one of the root nodes or a key obtained from openKey
+ * @param subkey a string to a subkey - if the subkey is empty or null the information will be obtained from the given key
+ * @return List on success and found a filled list with strings will be returned - on error or nothing found null will be returned
+ * @throws RegistryErrorException
+ ****************************************************************************************************************************/
+ public List listValueNames(int key, String subkey) throws RegistryErrorException
+ {
+ int handle = -1;
+ try{
+ handle = openKey(key, subkey, KEY_READ); //just reading priv
+ if(handle != -1)
+ {
+ int info[] = getChildInformation(handle); //obtain the informations
+ if(info != null && info[0] != -1)
+ {
+ List ret = new ArrayList();
+ for(int x = 0; x != info[2]; x++)
+ {
+ String tmp = parseValue(enumValueName(handle,x,info[4] + 1));
+ if(tmp != null) //just if not null, maybe there are no valueNames
+ ret.add(tmp);
+ }
+ return ret.isEmpty() ? null : ret;
+ }
+ }
+ }
+ catch(RegistryErrorException ex)
+ {
+ throw ex;
+ }
+ catch(Exception ex)
+ {
+ throw new RegistryErrorException(ex.getMessage());
+ }
+ finally{
+ closeKey(handle);
+ }
+ return null;
+ }
+
+ /*****************************************************************************************************************************
+ * Returns every valueName (not only the String value names)
+ * @param key either one of the root nodes or a key obtained from openKey
+ * @return List on success and found a filled list with strings will be returned - on error or nothing found null will be returned
+ * @throws RegistryErrorException
+ ****************************************************************************************************************************/
+ public List listValueNames(int key) throws RegistryErrorException
+ {
+ return listValueNames(key,null);
+ }
+
+ /******************************************************************************************************************************
+ * Reading the subkey name out of the registry (to obtain the count and the maxKeyNameLength use <code>getChildInformation</code>
+ * method
+ * @param key the handle to the key obtained by openKey
+ * @param subkeyIndex index from the subkey from which you want to obtain the name (start with 0 - the maximum count you get from
+ * getChildInformation method in array [0])
+ * @param maxKeyNameLength the maximum length of a subkey name (used because for memory allocating in the java.dll - if you obtain
+ * the size from getChildInformation increase the [3] int array by 1 )
+ * @return byte[] on error or not found or the maxKeyNameLength is to short it will returns null, on success the name of the subkey
+ * @throws RegistryErrorException
+ *****************************************************************************************************************************/
+ public byte[] enumKeys(int key, int subkeyIndex, int maxKeyNameLength) throws RegistryErrorException
+ {
+ try
+ {
+ return (byte[])enumKey.invoke(null, new Object[] {new Integer(key), new Integer(subkeyIndex), new Integer(maxKeyNameLength)});
+ }
+ catch (InvocationTargetException ex)
+ {
+ throw new RegistryErrorException(ex.getMessage());
+ }
+ catch (IllegalArgumentException ex)
+ {
+ throw new RegistryErrorException(ex.getMessage());
+ }
+ catch (IllegalAccessException ex)
+ {
+ throw new RegistryErrorException(ex.getMessage());
+ }
+ }
+
+ /******************************************************************************************************************************
+ * Returns all subkeys from the given key and subkey
+ * @param key either one of the root nodes or a key obtained from openKey
+ * @param subkey a string to a subkey - if the subkey is empty or null the information will be obtained from the given key
+ * @return List on success and found a filled list with strings will be returned - on error or nothing found null will be returned
+ * @throws RegistryErrorException
+ *****************************************************************************************************************************/
+ public List listKeys(int key, String subkey) throws RegistryErrorException
+ {
+ int handle = -1;
+ try{
+ handle = openKey(key, subkey, KEY_READ); //just reading priv
+ if(handle != -1)
+ {
+ int info[] = getChildInformation(handle); //obtain the informations
+ if(info != null && info[0] != -1)
+ {
+ List ret = new ArrayList();
+ for(int x = 0; x != info[0]; x++)
+ {
+ String tmp = parseValue(enumKeys(handle,x,info[3] + 1));
+ if(tmp != null) //just if not null, maybe there are no valueNames
+ ret.add(tmp);
+ }
+ return ret.isEmpty() ? null : ret;
+ }
+ }
+ }
+ catch(RegistryErrorException ex)
+ {
+ throw ex;
+ }
+ catch(Exception ex)
+ {
+ throw new RegistryErrorException(ex.getMessage());
+ }
+ finally{
+ closeKey(handle);
+ }
+ return null;
+ }
+
+ /*****************************************************************************************************************************
+ * Returns all subkeys from the given key
+ * @param key either one of the root nodes or a key obtained from openKey
+ * @return List on success and found a filled list with strings will be returned - on error or nothing found null will be returned
+ * @throws RegistryErrorException
+ ****************************************************************************************************************************/
+ public List listKeys(int key) throws RegistryErrorException
+ {
+ return listKeys(key,null);
+ }
+
+
+ /******************************************************************************************************************************
+ * Reads information about the current opened key (use it when you want to enumKey or enumValueName to determine the maximum
+ * key length and the count of keys)
+ * @param key the key which you obtained from openKey
+ * @return int[0] the count of the subkeys,[2] count of valuenames,
+ * [3] the maximum length of a subkey! the maximum length of valuename is stored in[4]
+ * (for other operations you should increase the [3] or [4] value by 1 because of the terminating \0 in C - because you handle
+ * with the java.dll)
+ * if nothing found or illegal key, the values are -1 of the array (at index 1 the value would be 6 the other -1)
+ * @throws RegistryErrorException
+ *****************************************************************************************************************************/
+ public int[] getChildInformation(int key) throws RegistryErrorException
+ {
+ try
+ {
+ return (int[])queryInfoKey.invoke(null, new Object[] {new Integer(key)});
+ }
+ catch (InvocationTargetException ex)
+ {
+ throw new RegistryErrorException(ex.getMessage());
+ }
+ catch (IllegalArgumentException ex)
+ {
+ throw new RegistryErrorException(ex.getMessage());
+ }
+ catch (IllegalAccessException ex)
+ {
+ throw new RegistryErrorException(ex.getMessage());
+ }
+ }
+
+ /******************************************************************************************************************************
+ * Method deletes the specified String value
+ * @param key the key obtained by openKey
+ * @param valueName name of String value you want to delete (if the string is empty or null the default entry will be
+ * deleted)
+ * @return int
+ * @throws RegistryErrorException
+ *****************************************************************************************************************************/
+ public int delValue(int key, String valueName) throws RegistryErrorException
+ {
+ try
+ {
+ Integer ret = (Integer)delValue.invoke(null, new Object[] {new Integer(key), getString(valueName)});
+ if(ret != null)
+ return ret.intValue();
+ else
+ return -1;
+ }
+ catch (InvocationTargetException ex)
+ {
+ throw new RegistryErrorException(ex.getMessage());
+ }
+ catch (IllegalArgumentException ex)
+ {
+ throw new RegistryErrorException(ex.getMessage());
+ }
+ catch (IllegalAccessException ex)
+ {
+ throw new RegistryErrorException(ex.getMessage());
+ }
+ }
+
+ /******************************************************************************************************************************
+ * Method set the specified string value
+ * Methode setzt (oder erstellt) einen Wert auf eine Zeichenfolge
+ * Will man den defaulteintrag �ndern, so muss man valueName "" �bergeben
+ * @param key obtained by openKey
+ * @param valueName the string value name in the registry you want to set
+ * @param value the new value you want to set
+ * @return on success, return is ERROR_SUCCESS if not -1 or sth else will be returned
+ * @throws RegistryErrorException
+ *****************************************************************************************************************************/
+ public int setValue(int key,String valueName, String value) throws RegistryErrorException
+ {
+ try
+ {
+ Integer ret = (Integer)setValue.invoke(null, new Object[] {new Integer(key), getString(valueName), getString(value)});
+ if(ret != null)
+ return ret.intValue();
+ else
+ return -1;
+ }
+ catch (InvocationTargetException ex)
+ {
+ throw new RegistryErrorException(ex.getMessage());
+ }
+ catch (IllegalArgumentException ex)
+ {
+ throw new RegistryErrorException(ex.getMessage());
+ }
+ catch (IllegalAccessException ex)
+ {
+ throw new RegistryErrorException(ex.getMessage());
+ }
+ }
+
+ /******************************************************************************************************************************
+ * Reads the value of an string value
+ * @param key obtained from openKey
+ * @param valueName the string value which you want to read (if you want to obtain the default entry the valueName should be
+ * empty or NULL)
+ * @return byte[] if found the data in the string value will be returned (to get a string use the class method parseValue(byte[]))
+ * on error NULL will be returned
+ * @throws RegistryErrorException
+ *****************************************************************************************************************************/
+ public byte[] readValue(int key, String valueName) throws RegistryErrorException
+ {
+ try
+ {
+ byte ret[] = (byte[])queryValue.invoke(null, new Object[] {new Integer(key), getString(valueName)});
+ return ret;
+ }
+ catch (InvocationTargetException ex)
+ {
+ throw new RegistryErrorException(ex.getMessage());
+ }
+ catch (IllegalArgumentException ex)
+ {
+ throw new RegistryErrorException(ex.getMessage());
+ }
+ catch (IllegalAccessException ex)
+ {
+ throw new RegistryErrorException(ex.getMessage());
+ }
+ }
+
+ /******************************************************************************************************************************
+ * Flush method - dont know what the method exactly does just implemented because i found it in the java sun source
+ * @param key obtained the key from openKey
+ * @return on success, ERROR_SUCESS will be returned! on error -1 or sth else
+ * @throws RegistryErrorException
+ *****************************************************************************************************************************/
+ public int flushKey(int key) throws RegistryErrorException
+ {
+ try
+ {
+ Integer ret = (Integer)flushKey.invoke(null, new Object[] {new Integer(key)});
+ if(ret != null)
+ return ret.intValue();
+ else
+ return -1;
+ }
+ catch (InvocationTargetException ex)
+ {
+ throw new RegistryErrorException(ex.getMessage());
+ }
+ catch (IllegalArgumentException ex)
+ {
+ throw new RegistryErrorException(ex.getMessage());
+ }
+ catch (IllegalAccessException ex)
+ {
+ throw new RegistryErrorException(ex.getMessage());
+ }
+ }
+
+ /******************************************************************************************************************************
+ * deletes a key/subkey from the registry
+ * @param key the parent key obtained by openKey
+ * @param subkey the key name you want to delete
+ * @return int ERROR_SUCCESS wenn erfolgreich
+ * @throws RegistryErrorException if subkey is empty or null or any other exception occurs
+ *****************************************************************************************************************************/
+ public int delKey(int key, String subkey) throws RegistryErrorException
+ {
+ if(subkey == null || subkey.length() == 0)
+ throw new RegistryErrorException("subkey cannot be null");
+ try
+ {
+ Integer ret = (Integer)delKey.invoke(null, new Object[] {new Integer(key), getString(subkey)});
+ if(ret != null)
+ return ret.intValue();
+ else
+ return -1;
+ }
+ catch (InvocationTargetException ex)
+ {
+ throw new RegistryErrorException(ex.getMessage());
+ }
+ catch (IllegalArgumentException ex)
+ {
+ throw new RegistryErrorException(ex.getMessage());
+ }
+ catch (IllegalAccessException ex)
+ {
+ throw new RegistryErrorException(ex.getMessage());
+ }
+ }
+
+ /******************************************************************************************************************************
+ * Create new key/subkey in the registry with the specified name
+ * Attentition: if the key is successfully returned, you should close and open the key again, because the obtained key
+ * doesnt have a high access level (so maybe creating or deleting a key/value wouldn�t be successful)
+ * @param key handle to parent key obtained from openKey
+ * @param subkey name of the key/subkey you want to create
+ * @return on success the handle to the new key will be returned, otherwhise it will be -1
+ * @throws RegistryErrorException
+ *****************************************************************************************************************************/
+ public int createKey(int key, String subkey) throws RegistryErrorException
+ {
+ try
+ {
+ int result[] = (int[])createKey.invoke(null, new Object[] {new Integer(key), getString(subkey)});
+ if(result[ERROR_CODE] == ERROR_SUCCESS)
+ return result[NATIVE_HANDLE];
+ else
+ return -1;
+ }
+ catch (InvocationTargetException ex)
+ {
+ throw new RegistryErrorException(ex.getMessage());
+ }
+ catch (IllegalArgumentException ex)
+ {
+ throw new RegistryErrorException(ex.getMessage());
+ }
+ catch (IllegalAccessException ex)
+ {
+ throw new RegistryErrorException(ex.getMessage());
+ }
+ }
+
+
+
+ /*****************************************************************************************************************************
+ * Close an obtained key for right usage
+ * @param key the key handle
+ * @return int on error it will be -1
+ * @throws RegistryErrorException
+ ****************************************************************************************************************************/
+ public int closeKey(int key) throws RegistryErrorException
+ {
+ try
+ {
+ Integer ret = (Integer)closeKey.invoke(null, new Object[] {new Integer(key)});
+ if(ret != null)
+ return ret.intValue();
+ else
+ return -1;
+ }
+ catch (InvocationTargetException ex)
+ {
+ throw new RegistryErrorException(ex.getMessage());
+ }
+ catch (IllegalArgumentException ex)
+ {
+ throw new RegistryErrorException(ex.getMessage());
+ }
+ catch (IllegalAccessException ex)
+ {
+ throw new RegistryErrorException(ex.getMessage());
+ }
+ }
+
+ /******************************************************************************************************************************
+ * Opens a registry key
+ * @param key one of the registry root nodes - either HKEY_CLASSES_ROOT, HKEY_CURRENT_USER or HKEY_LOCAL_MACHINE
+ * @param subkey the name of the key/subkey like SOFTWARE or HARDWARE - for subkeys use the \\ as delimiter f.e. : SOFTWARE\\MICROSOFT
+ * if subkey name is "" or null it returns the handle to the root node
+ * @param security_mask the security mask to handle with the opened key (see security mask doc at the begin for detailed information)
+ * @return int on error -1 (when not found or not allowed) otherwhise the handle to the obtained key
+ * @throws RegistryErrorException
+ *****************************************************************************************************************************/
+ public int openKey(int key, String subkey, int security_mask) throws RegistryErrorException
+ {
+ try
+ {
+ int[] result = (int[])openKey.invoke(null, new Object[]{new Integer(key),getString(subkey),new Integer(security_mask)});
+ if(result == null || result[ERROR_CODE] != ERROR_SUCCESS)
+ return -1;
+ else
+ return result[NATIVE_HANDLE];
+ }
+ catch (InvocationTargetException ex1)
+ {
+ throw new RegistryErrorException(ex1.getMessage());
+ }
+ catch (IllegalArgumentException ex1)
+ {
+ throw new RegistryErrorException(ex1.getMessage());
+ }
+ catch (IllegalAccessException ex1)
+ {
+ throw new RegistryErrorException(ex1.getMessage());
+ }
+ }
+
+ /******************************************************************************************************************************
+ * Opens a registry key
+ * @param key one of the registry root nodes - either HKEY_CLASSES_ROOT, HKEY_CURRENT_USER or HKEY_LOCAL_MACHINE
+ * @param subkey the name of the key/subkey like SOFTWARE or HARDWARE - for subkeys use the \\ as delimiter f.e. : SOFTWARE\\MICROSOFT
+ * if subkey name is "" or null it returns the handle to the root node
+ * @return int -1 if not found or not allowed (attention here this methods allways uses the KEY_ALL_ACCESS security mask)
+ * on success the handle to key will be returned
+ * @throws RegistryErrorException
+ *****************************************************************************************************************************/
+ public int openKey(int key, String subkey) throws RegistryErrorException
+ {
+ return openKey(key,subkey,KEY_ALL_ACCESS);
+ }
+
+ /******************************************************************************************************************************
+ * Intern method which adds the trailing \0 for the handle with java.dll
+ * @param str String
+ * @return byte[]
+ *****************************************************************************************************************************/
+ private byte[] getString(String str)
+ {
+ if(str == null)
+ str = "";
+ return (str += "\0").getBytes();
+ }
+
+ /******************************************************************************************************************************
+ * Method removes the trailing \0 which is returned from the java.dll (just if the last sign is a \0)
+ * @param buf the byte[] buffer which every read method returns
+ * @return String a parsed string without the trailing \0
+ *****************************************************************************************************************************/
+ public static String parseValue(byte buf[])
+ {
+ if(buf == null)
+ return null;
+ String ret = new String(buf);
+ if(ret.charAt(ret.length() - 1) == '\0')
+ return ret.substring(0,ret.length() - 1);
+ return ret;
+ }
+
+
+ /******************************************************************************************************************************
+ * intern method which obtain the methods via reflection from the java.util.prefs.WindowPreferences (tested with java 1.4, 1.5
+ * and java 1.6)
+ * @throws RegistryErrorException exception is thrown if any method is not found or if the class is not found
+ *****************************************************************************************************************************/
+ private void initMethods() throws RegistryErrorException
+ {
+ Class clazz = null;
+ try
+ {
+ clazz = Class.forName("java.util.prefs.WindowsPreferences"); //da der Zugriff anders nicht erlaubt wird
+
+ Method ms[] = clazz.getDeclaredMethods();
+ if(ms == null)
+ throw new RegistryErrorException("Cannot access java.util.prefs.WindowsPreferences class!");
+ //geht die Methoden durch und speichert diese in den Variablen ab
+ for(int x = 0; x != ms.length; x++)
+ {
+ if(ms[x] != null)
+ {
+ if(ms[x].getName().equals("WindowsRegOpenKey"))
+ {
+ openKey = ms[x];
+ openKey.setAccessible(true); //set Access for private
+ }
+ else if(ms[x].getName().equals("WindowsRegCloseKey"))
+ {
+ closeKey = ms[x];
+ closeKey.setAccessible(true);
+ }
+ else if(ms[x].getName().equals("WindowsRegCreateKeyEx"))
+ {
+ createKey = ms[x];
+ createKey.setAccessible(true);
+ }
+ else if(ms[x].getName().equals("WindowsRegDeleteKey"))
+ {
+ delKey = ms[x];
+ delKey.setAccessible(true);
+ }
+ else if(ms[x].getName().equals("WindowsRegFlushKey"))
+ {
+ flushKey = ms[x];
+ flushKey.setAccessible(true);
+ }
+ else if(ms[x].getName().equals("WindowsRegQueryValueEx"))
+ {
+ queryValue = ms[x];
+ queryValue.setAccessible(true);
+ }
+ else if(ms[x].getName().equals("WindowsRegSetValueEx"))
+ {
+ setValue = ms[x];
+ setValue.setAccessible(true);
+ }
+ else if(ms[x].getName().equals("WindowsRegDeleteValue"))
+ {
+ delValue = ms[x];
+ delValue.setAccessible(true);
+ }
+ else if(ms[x].getName().equals("WindowsRegQueryInfoKey"))
+ {
+ queryInfoKey = ms[x];
+ queryInfoKey.setAccessible(true);
+ }
+ else if(ms[x].getName().equals("WindowsRegEnumKeyEx"))
+ {
+ enumKey = ms[x];
+ enumKey.setAccessible(true);
+ }
+ else if(ms[x].getName().equals("WindowsRegEnumValue"))
+ {
+ enumValue = ms[x];
+ enumValue.setAccessible(true);
+ }
+ }
+ }
+ }
+ catch (ClassNotFoundException ex)
+ {
+ throw new RegistryErrorException(ex.getMessage());
+ }
+ }
+
+
+ /******************************************************************************************************************************
+ * main for testing and some examples are stored here
+ * @param args String[]
+ * @throws Exception
+ *****************************************************************************************************************************/
+ public static void main(String[] args) throws Exception
+ {
+ Regor regor = new Regor();
+ //opening dhe LOCAL_MACHINE entry and software\microsoft - the delimiter is the \\
+ int key = regor.openKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft"), key2 = -1;
+ //listing the subkeys
+ List l = regor.listKeys(key);
+ System.out.println("SOME KEYS....");
+ for(int x = 0; l != null && x != l.size(); x++) //printing out the keys
+ System.out.println(x + " == " + l.get(x));
+ if(l.size() > 0) //if keys found, use first key to get valueNames
+ key2 = regor.openKey(key,(String)l.get(0));
+ l = regor.listValueNames(key2); //read the valueNames
+ System.out.println("SOME VALUENAMES.....");
+ for(int x = 0; l != null && x != l.size(); x++) //printing it
+ System.out.println(x + " == " + l.get(x));
+ System.out.println("SOME STRING VALUES....");
+ for(int x = 0; l != null && x != l.size(); x++) //getting the String value from the valueNames
+ {
+ byte buf[] = regor.readValue(key2,(String)l.get(x)); //get the information - if is not a string value, null will be returned
+ System.out.println(x + ": " + l.get(x) + " == " + Regor.parseValue(buf)); //parses the byte buffer to String
+ }
+ //example to access the default valueName - either null or ""
+ System.out.println("default entry == " + Regor.parseValue(regor.readValue(key,null)));
+ //accessing a root node
+ l = regor.listKeys(HKEY_LOCAL_MACHINE);
+ System.out.println("KEYS FROM LOCAL_MACHINE....");
+ for(int x = 0; l != null && x != l.size(); x++) //printing out the keys
+ System.out.println(x + " == " + l.get(x));
+ regor.closeKey(key2);
+ regor.closeKey(key);
+ }
+}
diff --git a/source/edu/stanford/ejalbert/BrowserLauncher.java b/source/edu/stanford/ejalbert/BrowserLauncher.java
new file mode 100644
index 0000000..d7f63ad
--- /dev/null
+++ b/source/edu/stanford/ejalbert/BrowserLauncher.java
@@ -0,0 +1,407 @@
+/************************************************
+ Copyright 2004,2005,2006,2007 Markus Gebhard, Jeff Chapman
+
+ This file is part of BrowserLauncher2.
+
+ BrowserLauncher2 is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ BrowserLauncher2 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with BrowserLauncher2; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ ************************************************/
+// $Id: BrowserLauncher.java,v 1.13 2007/08/27 14:12:51 jchapman0 Exp $
+package edu.stanford.ejalbert;
+
+import java.util.List;
+
+import edu.stanford.ejalbert.exception.BrowserLaunchingExecutionException;
+import edu.stanford.ejalbert.exception.BrowserLaunchingInitializingException;
+import edu.stanford.ejalbert.exception.UnsupportedOperatingSystemException;
+import edu.stanford.ejalbert.exceptionhandler.
+ BrowserLauncherDefaultErrorHandler;
+import edu.stanford.ejalbert.exceptionhandler.BrowserLauncherErrorHandler;
+import edu.stanford.ejalbert.launching.BrowserLaunchingFactory;
+import edu.stanford.ejalbert.launching.IBrowserLaunching;
+import net.sf.wraplog.AbstractLogger;
+import net.sf.wraplog.NoneLogger;
+
+/**
+ * BrowserLauncher provides an API to open browsers (default or
+ * targetted) from within a Java application.
+ * <p>
+ * Primary API methods:
+ * <p>
+ * {@link #openURLinBrowser(String, String) openURLinBrowser(browser, url)}
+ * Opens the url in the requested browser.
+ * <p>
+ * {@link #openURLinBrowser(String) openURLinBrowser(url)}
+ * Opens the url in the default browser.
+ * <p>
+ * {@link #getBrowserList getBrowserList()}
+ * Returns the list of browsers that are available for browser
+ * targetting.
+ * <p>
+ * The following protocols have been tested: http, mailto, and file.
+ * <p>
+ * This library is written completely in Java and will run on
+ * all JDK 4.x-compliant systems without modification or a need
+ * for additional libraries.
+ * <p>
+ * There are certain system requirements for this library, as
+ * it's running through Runtime.exec(), which is Java's way of
+ * making a native system call. Currently, Macintosh requires a
+ * Finder which supports the GURL event, which is true for Mac OS
+ * 8.0 and 8.1 systems that have the Internet Scripting
+ * AppleScript dictionary installed in the Scripting Additions
+ * folder in the Extensions folder (which is installed by default,
+ * as far as the library authors know, under Mac OS 8.0 and 8.1),
+ * and for all Mac OS 8.5 and later systems. On Windows, it only
+ * runs under Win32 systems (Windows 9x and NT 4.0, as well as
+ * later versions).
+ * <p>
+ * The browserlauncher2 project is based on the original
+ * browserlauncher project. It has been significantly altered
+ * and extended.</br/>
+ * <b>This is the original copyright notice and credits from the
+ * browserlauncher project:</b><br/>
+ * This code is Copyright 1999-2001 by Eric Albert (ejalbert at cs.stanford.edu) and may be
+ * redistributed or modified in any form without restrictions as long as the portion of this
+ * comment from this paragraph through the end of the comment is not removed. The author
+ * requests that he be notified of any application, applet, or other binary that makes use of
+ * this code, but that's more out of curiosity than anything and is not required. This software
+ * includes no warranty. The author is not repsonsible for any loss of data or functionality
+ * or any adverse or unexpected effects of using this software.
+ * <p>
+ * Credits:
+ * <br>Steven Spencer, JavaWorld magazine (<a href="http://www.javaworld.com/javaworld/javatips/jw-javatip66.html">Java Tip 66</a>)
+ * <br>Thanks also to Ron B. Yeh, Eric Shapiro, Ben Engber, Paul Teitlebaum, Andrea Cantatore,
+ * Larry Barowski, Trevor Bedzek, Frank Miedrich, and Ron Rabakukk
+ * <br/><b>End of the original copyright and credits.</b>
+ * @author Eric Albert
+ * @author Markus Gebhard
+ * @author Jeff Chapman
+ */
+public class BrowserLauncher {
+ /**
+ * Key to system property containing name of users
+ * preferred browser.
+ * <p>
+ * The value is defined in IBrowserLaunching but exposed for
+ * general API usage from the BrowserLauncher class.
+ */
+ public static final String BROWSER_SYSTEM_PROPERTY =
+ IBrowserLaunching.BROWSER_SYSTEM_PROPERTY;
+ /**
+ * Key to system property that controls how browsers are discovered
+ * when running on a Windows O/S. The values are registry and disk.
+ * <p>
+ * The value is defined in IBrowserLaunching but exposed for
+ * general API usage from the BrowserLauncher class.
+ */
+ public static final String WINDOWS_BROWSER_DISC_POLICY_PROPERTY =
+ IBrowserLaunching.WINDOWS_BROWSER_DISC_POLICY_PROPERTY;
+ /**
+ * Value associated with WINDOWS_BROWSER_DISC_POLICY_PROPERTY.
+ * <p>
+ * The value is defined in IBrowserLaunching but exposed for
+ * general API usage from the BrowserLauncher class.
+ */
+ public static final String WINDOWS_BROWSER_DISC_POLICY_DISK =
+ IBrowserLaunching.WINDOWS_BROWSER_DISC_POLICY_DISK;
+ /**
+ * Value associated with WINDOWS_BROWSER_DISC_POLICY_PROPERTY.
+ * <p>
+ * The value is defined in IBrowserLaunching but exposed for
+ * general API usage from the BrowserLauncher class.
+ */
+ public static final String WINDOWS_BROWSER_DISC_POLICY_REGISTRY =
+ IBrowserLaunching.WINDOWS_BROWSER_DISC_POLICY_REGISTRY;
+
+ private final IBrowserLaunching launching; // in ctor
+ private AbstractLogger logger; // in init method
+ private BrowserLauncherErrorHandler errorHandler; // in ctor
+
+ /**
+ * Initializes the browser launcher for the operating system on which
+ * the application is running.
+ * <p>
+ * This method will use the default logger
+ * {@link net.sf.wraplog.NoneLogger NoneLogger}. All log messages are
+ * ignored by this logger.
+ * <p>
+ * This method will use the default errorHandler
+ * {@link edu.stanford.ejalbert.exceptionhandler.BrowserLauncherDefaultErrorHandler BrowserLauncherDefaultErrorHandler}.
+ * It will print a stack trace to the console. The errorHandler is used
+ * to catch and handle exceptions when executing the browser
+ * launch in a separate thread.
+ *
+ * @throws BrowserLaunchingInitializingException
+ * @throws UnsupportedOperatingSystemException
+ */
+ public BrowserLauncher()
+ throws BrowserLaunchingInitializingException,
+ UnsupportedOperatingSystemException {
+ this(null, null);
+ }
+
+ /**
+ * Initializes the browser launcher for the operating system on which
+ * the application is running.
+ * <p>
+ * If null is passed in as a logger, the default logger used will
+ * be {@link net.sf.wraplog.NoneLogger NoneLogger}. All log messages are
+ * ignored by this logger.
+ * <p>
+ * This method will use the default errorHandler
+ * {@link edu.stanford.ejalbert.exceptionhandler.BrowserLauncherDefaultErrorHandler BrowserLauncherDefaultErrorHandler}.
+ * It will print a stack trace to the console. The errorHandler is used
+ * to catch and handle exceptions when executing the browser
+ * launch in a separate thread.
+
+ * @param logger AbstractLogger
+ * @throws BrowserLaunchingInitializingException
+ * @throws UnsupportedOperatingSystemException
+ */
+ public BrowserLauncher(AbstractLogger logger)
+ throws BrowserLaunchingInitializingException,
+ UnsupportedOperatingSystemException {
+ this(logger, null);
+ }
+
+ /**
+ * Initializes the browser launcher for the operating system on which
+ * the application is running.
+ * <p>
+ * If null is passed in as a logger, the default logger used will
+ * be {@link net.sf.wraplog.NoneLogger NoneLogger}. All log messages are
+ * ignored by this logger.
+ * <p>
+ * If null is passed for the errorHandler, the default errorHandler
+ * used will be
+ * {@link edu.stanford.ejalbert.exceptionhandler.BrowserLauncherDefaultErrorHandler BrowserLauncherDefaultErrorHandler}.
+ * It will print a stack trace to the console. The errorHandler is used
+ * to catch and handle exceptions when executing the browser
+ * launch in a separate thread.
+ *
+ * @param logger AbstractLogger
+ * @param errorHandler BrowserLauncherErrorHandler
+ * @throws BrowserLaunchingInitializingException
+ * @throws UnsupportedOperatingSystemException
+ */
+ public BrowserLauncher(AbstractLogger logger,
+ BrowserLauncherErrorHandler errorHandler)
+ throws BrowserLaunchingInitializingException,
+ UnsupportedOperatingSystemException {
+ // assign logger or use default
+ if (logger == null) {
+ logger = new NoneLogger();
+ }
+ this.logger = logger;
+ // assign error handler or use default
+ if (errorHandler == null) {
+ errorHandler = new BrowserLauncherDefaultErrorHandler();
+ }
+ this.errorHandler = errorHandler;
+ // init and assign IBrowserLaunching instance
+ // this method assumes the logger is not null
+ this.launching = initBrowserLauncher();
+ }
+
+ /**
+ * Determines the operating system and loads the necessary runtime data.
+ * <p>
+ * If null is passed in as a logger, the default logger used will
+ * be {@link net.sf.wraplog.NoneLogger NoneLogger}. All log messages are
+ * ignored by this logger.
+ *
+ * @param logger AbstractLogger
+ * @return IBrowserLaunching
+ * @throws UnsupportedOperatingSystemException
+ * @throws BrowserLaunchingInitializingException
+ */
+ private IBrowserLaunching initBrowserLauncher()
+ throws UnsupportedOperatingSystemException,
+ BrowserLaunchingInitializingException {
+ if (logger == null) {
+ throw new IllegalArgumentException(
+ "the logger cannot be null at this point.");
+ }
+ IBrowserLaunching launching =
+ BrowserLaunchingFactory.createSystemBrowserLaunching(logger);
+ launching.initialize();
+ return launching;
+ }
+
+ /**
+ * Attempts to open the default web browser to the given URL.
+ * @deprecated -- create a BrowserLauncher object and use it instead of
+ * calling this static method.
+ * @param urlString The URL to open
+ * @throws UnsupportedOperatingSystemException
+ * @throws BrowserLaunchingExecutionException
+ * @throws BrowserLaunchingInitializingException
+ */
+ public static void openURL(String urlString)
+ throws UnsupportedOperatingSystemException,
+ BrowserLaunchingExecutionException,
+ BrowserLaunchingInitializingException {
+ BrowserLauncher launcher = new BrowserLauncher(null);
+ launcher.openURLinBrowser(urlString);
+ }
+
+ /**
+ * Opens a browser and url from the command line. Useful for testing.
+ * The first argument is the url to be opened. All other arguments will
+ * be ignored.
+ *
+ * @param args String[]
+ */
+ public static void main(String[] args) {
+ if (args.length == 0) {
+ System.err.println("Usage: java -jar BrowserLauncher.jar url_value");
+ }
+ else {
+ try {
+ BrowserLauncher launcher = new BrowserLauncher(null);
+ launcher.openURLinBrowser(args[0]);
+ }
+ catch (BrowserLaunchingInitializingException ex) {
+ ex.printStackTrace();
+ }
+ //catch (BrowserLaunchingExecutionException ex) {
+ // ex.printStackTrace();
+ // }
+ catch (UnsupportedOperatingSystemException ex) {
+ ex.printStackTrace();
+ }
+ }
+ }
+
+ /* ---------------------- API Methods -------------------- */
+
+ /**
+ * Returns the logger being used by this BrowserLauncher instance.
+ *
+ * @return AbstractLogger
+ */
+ public AbstractLogger getLogger() {
+ return logger;
+ }
+
+ /**
+ * Returns a list of browsers to be used for browser targetting.
+ * This list will always contain at least one item:
+ * {@link edu.stanford.ejalbert.launching.IBrowserLaunching#BROWSER_DEFAULT BROWSER_DEFAULT}.
+ * @see IBrowserLaunching
+ * @return List
+ */
+ public List getBrowserList() {
+ return launching.getBrowserList();
+ }
+
+ /**
+ * Attempts to open a browser and direct it to the passed url.
+ *
+ * @todo what to do if the url is null or empty?
+ * @param urlString String
+ */
+ public void openURLinBrowser(String urlString) {
+ Runnable runner = new BrowserLauncherRunner(
+ launching,
+ urlString,
+ logger,
+ errorHandler);
+ Thread launcherThread = new Thread(runner);
+ launcherThread.start();
+ }
+
+ /**
+ * Attempts to open a specific browser and direct it to the passed url. If
+ * the call to the requested browser fails, the code will fail over to the
+ * default browser.
+ * <p>
+ * The name for the targetted browser should come from the list
+ * returned from {@link #getBrowserList() getBrowserList}.
+ *
+ * @param browser String
+ * @param urlString String
+ */
+ public void openURLinBrowser(String browser,
+ String urlString) {
+ Runnable runner = new BrowserLauncherRunner(
+ launching,
+ browser,
+ urlString,
+ logger,
+ errorHandler);
+ Thread launcherThread = new Thread(runner);
+ launcherThread.start();
+ }
+
+ /**
+ * Iterates through the list of browsers until it finds one
+ * that is available on the user's system. The method then
+ * opens the browser and directs it to the passed url. This
+ * method allows the caller to try multiple browsers in a
+ * specific order.
+ * <p>
+ * If the list is null or empty or none of the browsers in
+ * the list are available, the code will fail over to the
+ * default browser method
+ * {@link #openURLinBrowser(String) openURLinBrowser(url)}.
+ * <p>
+ * The name for the targetted browsers should come from the
+ * list returned from
+ * {@link #getBrowserList() getBrowserList}.
+ *
+ * @param browsers List
+ * @param urlString String
+ */
+ public void openURLinBrowser(List browsers,
+ String urlString) {
+ Runnable runner = new BrowserLauncherRunner(
+ launching,
+ browsers,
+ urlString,
+ logger,
+ errorHandler);
+ Thread launcherThread = new Thread(runner);
+ launcherThread.start();
+ }
+
+ /**
+ * Returns the policy used for opening a url in a browser.
+ * <p>
+ * If the policy is true, an attempt will be made to force the
+ * url to be opened in a new instance (window) of the
+ * browser.
+ * <p>
+ * If the policy is false, the url may open in a new window or
+ * a new tab.
+ * <p>
+ * Results will vary based on the O/S and browser being targetted.
+ *
+ * @return boolean
+ */
+ public boolean getNewWindowPolicy() {
+ return launching.getNewWindowPolicy();
+ }
+
+ /**
+ * Sets the policy used for opening a url in a browser.
+ *
+ * @param forceNewWindow boolean
+ */
+ public void setNewWindowPolicy(boolean forceNewWindow) {
+ launching.setNewWindowPolicy(forceNewWindow);
+ }
+}
diff --git a/source/edu/stanford/ejalbert/BrowserLauncherRunner.java b/source/edu/stanford/ejalbert/BrowserLauncherRunner.java
new file mode 100644
index 0000000..113f5ef
--- /dev/null
+++ b/source/edu/stanford/ejalbert/BrowserLauncherRunner.java
@@ -0,0 +1,144 @@
+/************************************************
+ Copyright 2005,2006 Jeff Chapman
+
+ This file is part of BrowserLauncher2.
+
+ BrowserLauncher2 is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ BrowserLauncher2 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with BrowserLauncher2; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ ************************************************/
+// $Id: BrowserLauncherRunner.java,v 1.6 2006/04/11 13:36:48 jchapman0 Exp $
+package edu.stanford.ejalbert;
+
+import edu.stanford.ejalbert.exceptionhandler.BrowserLauncherErrorHandler;
+import edu.stanford.ejalbert.launching.IBrowserLaunching;
+import net.sf.wraplog.AbstractLogger;
+import java.util.List;
+
+/**
+ * This is a convenience class to facilitate executing the browser launch in
+ * a separate thread. This class is used from within BrowserLauncher
+ * when handling calls to open a url.
+ *
+ * @author Jeff Chapman
+ */
+class BrowserLauncherRunner
+ implements Runnable {
+ private final List targetBrowsers; // in ctor
+ private final String targetBrowser; // in ctor
+ private final String url; // in ctor
+ private final BrowserLauncherErrorHandler errorHandler; // in ctor
+ private final IBrowserLaunching launcher; // in ctor
+ private final AbstractLogger logger; // in ctor
+
+ /**
+ * Takes the items necessary for launching a browser and handling any
+ * exceptions.
+ *
+ * @param launcher IBrowserLaunching
+ * @param url String
+ * @param logger AbstractLogger
+ * @param errorHandler BrowserLauncherErrorHandler
+ */
+ BrowserLauncherRunner(IBrowserLaunching launcher,
+ String url,
+ AbstractLogger logger,
+ BrowserLauncherErrorHandler errorHandler) {
+ this(launcher, null, null, url, logger, errorHandler);
+ }
+
+ BrowserLauncherRunner(IBrowserLaunching launcher,
+ String browserName,
+ String url,
+ AbstractLogger logger,
+ BrowserLauncherErrorHandler errorHandler) {
+ this(launcher, browserName, null, url, logger, errorHandler);
+ }
+
+ BrowserLauncherRunner(IBrowserLaunching launcher,
+ List browserList,
+ String url,
+ AbstractLogger logger,
+ BrowserLauncherErrorHandler errorHandler) {
+ this(launcher, null, browserList, url, logger, errorHandler);
+ }
+
+ /**
+ * Takes the items necessary for launching a browser and handling any
+ * exceptions.
+ *
+ * @param launcher IBrowserLaunching
+ * @param browserName String
+ * @param url String
+ * @param logger AbstractLogger
+ * @param errorHandler BrowserLauncherErrorHandler
+ */
+ private BrowserLauncherRunner(IBrowserLaunching launcher,
+ String browserName,
+ List browserList,
+ String url,
+ AbstractLogger logger,
+ BrowserLauncherErrorHandler errorHandler) {
+ if (launcher == null) {
+ throw new IllegalArgumentException("launcher cannot be null.");
+ }
+ if (url == null) {
+ throw new IllegalArgumentException("url cannot be null.");
+ }
+ if (errorHandler == null) {
+ throw new IllegalArgumentException("errorHandler cannot be null.");
+ }
+ if (logger == null) {
+ throw new IllegalArgumentException("logger cannot be null");
+ }
+ this.targetBrowsers = browserList;
+ this.launcher = launcher;
+ this.url = url;
+ this.targetBrowser = browserName;
+ this.errorHandler = errorHandler;
+ this.logger = logger;
+ }
+
+ /* ------------------- from Runnable -------------------- */
+
+ /**
+ * When an object implementing interface <code>Runnable</code> is used to
+ * create a thread, starting the thread causes the object's
+ * <code>run</code> method to be called in that separately executing
+ * thread.
+ * <p>
+ * This method will make the call to open the browser and display the
+ * url. If an exception occurs, it will be passed to the instance of
+ * BrowserLauncherErrorHandler that has been passed into the constructor.
+ */
+ public void run() {
+ try {
+ if (targetBrowser != null) {
+ launcher.openUrl(targetBrowser,
+ url);
+ }
+ else if(targetBrowsers != null) {
+ launcher.openUrl(targetBrowsers,
+ url);
+ }
+ else {
+ launcher.openUrl(url);
+ }
+ }
+ catch (Exception ex) {
+ logger.error("fatal error opening url", ex);
+ errorHandler.handleException(ex);
+ }
+ }
+}
diff --git a/source/edu/stanford/ejalbert/browserprefui/BrowserPrefAction.java b/source/edu/stanford/ejalbert/browserprefui/BrowserPrefAction.java
new file mode 100644
index 0000000..c2d6c18
--- /dev/null
+++ b/source/edu/stanford/ejalbert/browserprefui/BrowserPrefAction.java
@@ -0,0 +1,104 @@
+/************************************************
+ Copyright 2006 Jeff Chapman
+
+ This file is part of BrowserLauncher2.
+
+ BrowserLauncher2 is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ BrowserLauncher2 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with BrowserLauncher2; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ ************************************************/
+// $Id: BrowserPrefAction.java,v 1.1 2006/09/26 19:40:28 jchapman0 Exp $
+package edu.stanford.ejalbert.browserprefui;
+
+import java.awt.event.ActionEvent;
+
+import javax.swing.AbstractAction;
+import javax.swing.Icon;
+import javax.swing.JFrame;
+import javax.swing.SwingUtilities;
+
+import edu.stanford.ejalbert.BrowserLauncher;
+
+/**
+ *
+ * @author Jeff Chapman
+ * @version 1.0
+ */
+public class BrowserPrefAction
+ extends AbstractAction {
+ private final BrowserLauncher browserLauncher; // in ctor
+ private final JFrame appFrame; // in ctor
+
+ public BrowserPrefAction(String name,
+ BrowserLauncher browserLauncher,
+ JFrame appFrame) {
+ super(name);
+ if(browserLauncher == null) {
+ throw new IllegalArgumentException("browserLauncher cannot be null");
+ }
+ this.browserLauncher = browserLauncher;
+ this.appFrame = appFrame;
+ }
+
+ public BrowserPrefAction(String name,
+ Icon icon,
+ BrowserLauncher browserLauncher,
+ JFrame appFrame) {
+ super(name, icon);
+ if(browserLauncher == null) {
+ throw new IllegalArgumentException("browserLauncher cannot be null");
+ }
+ this.browserLauncher = browserLauncher;
+ this.appFrame = appFrame;
+ }
+
+ /* --------------------------- from Action --------------------------- */
+
+ /**
+ * Launches a browser preferences dialog and sets the system
+ * property BrowserLauncher.BROWSER_SYSTEM_PROPERTY with
+ * the requested browser.
+ * <p>
+ * Browser prefs dialog will be placed in the Swing thread queue
+ * to enable action performed method to return immediately.
+ *
+ * @param e ActionEvent
+ */
+ public void actionPerformed(ActionEvent e) {
+ final ActionEvent event = e;
+ Runnable runner = new Runnable() {
+ public void run() {
+ try {
+ BrowserPrefDialog dlg = new BrowserPrefDialog(
+ appFrame,
+ browserLauncher);
+ dlg.setLocationRelativeTo(appFrame);
+ dlg.pack();
+ dlg.setSize(275,200);
+ dlg.setVisible(true);
+ String prefBrowser = dlg.getSelectedBrowser();
+ if(prefBrowser != null) {
+ System.setProperty(
+ BrowserLauncher.BROWSER_SYSTEM_PROPERTY,
+ prefBrowser);
+ }
+ }
+ catch (Exception ex) {
+ browserLauncher.getLogger().error("problem getting/setting browser pref", ex);
+ }
+ }
+ };
+ SwingUtilities.invokeLater(runner);
+ }
+}
diff --git a/source/edu/stanford/ejalbert/browserprefui/BrowserPrefDialog.java b/source/edu/stanford/ejalbert/browserprefui/BrowserPrefDialog.java
new file mode 100644
index 0000000..eddc2e6
--- /dev/null
+++ b/source/edu/stanford/ejalbert/browserprefui/BrowserPrefDialog.java
@@ -0,0 +1,130 @@
+/************************************************
+ Copyright 2006 Jeff Chapman
+
+ This file is part of BrowserLauncher2.
+
+ BrowserLauncher2 is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ BrowserLauncher2 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with BrowserLauncher2; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ ************************************************/
+// $Id: BrowserPrefDialog.java,v 1.1 2006/09/26 19:40:28 jchapman0 Exp $
+package edu.stanford.ejalbert.browserprefui;
+
+import java.awt.BorderLayout;
+import java.awt.Dialog;
+import java.awt.Frame;
+import java.awt.HeadlessException;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.List;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JList;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.ListSelectionModel;
+
+import edu.stanford.ejalbert.BrowserLauncher;
+
+/**
+ *
+ * @author Jeff Chapman
+ * @version 1.0
+ */
+public class BrowserPrefDialog
+ extends JDialog {
+ private JList browserList = new JList();
+ private String selectedBrowser = null;
+ private static final String UI_BUNDLE =
+ "edu.stanford.ejalbert.browserprefui.BrowserPrefs";
+
+ public BrowserPrefDialog(Dialog owner,
+ BrowserLauncher launcher)
+ throws HeadlessException {
+ super(owner, true);
+ initDialog(launcher);
+ }
+
+ public BrowserPrefDialog(Frame owner,
+ BrowserLauncher launcher)
+ throws HeadlessException {
+ super(owner, true);
+ initDialog(launcher);
+ }
+
+ public String getSelectedBrowser() {
+ return selectedBrowser;
+ }
+
+ private void initDialog(BrowserLauncher launcher)
+ throws MissingResourceException {
+ this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
+ // get resource bundle
+ ResourceBundle rbundle = ResourceBundle.getBundle(UI_BUNDLE);
+ // set title
+ this.setTitle(rbundle.getString("dialog.title"));
+ // init list of browsers
+ List browsers = launcher.getBrowserList();
+ browserList.setListData(browsers.toArray());
+ browserList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ // get selected browser from system prop
+ String prefBrowser = System.getProperty(
+ BrowserLauncher.BROWSER_SYSTEM_PROPERTY,
+ null);
+ if(prefBrowser != null) {
+ browserList.setSelectedValue(prefBrowser, true);
+ }
+ initGui(rbundle);
+ }
+
+ private void okButtonClicked() {
+ selectedBrowser = (String)browserList.getSelectedValue();
+ dispose();
+ }
+
+ private void cancelButtonClicked() {
+ dispose();
+ }
+
+ private void initGui(ResourceBundle rbundle)
+ throws MissingResourceException {
+ JButton okButton = new JButton(rbundle.getString("dialog.bttn.ok"));
+ JButton cancelButton = new JButton(rbundle.getString("dialog.bttn.cancel"));
+ JScrollPane browserListScroll = new JScrollPane(browserList);
+ // init ok button
+ okButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent ae) {
+ okButtonClicked();
+ }
+ });
+ // init cancel button
+ cancelButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent ae) {
+ cancelButtonClicked();
+ }
+ });
+ // create panels
+ JPanel mainPanel = new JPanel(new BorderLayout(0,2));
+ JPanel buttonsPanel = new JPanel();
+ // format controls
+ buttonsPanel.add(okButton);
+ buttonsPanel.add(cancelButton);
+ mainPanel.add(browserListScroll, BorderLayout.CENTER);
+ mainPanel.add(buttonsPanel, BorderLayout.SOUTH);
+ this.getContentPane().add(mainPanel);
+ }
+}
diff --git a/source/edu/stanford/ejalbert/browserprefui/BrowserPrefs.properties b/source/edu/stanford/ejalbert/browserprefui/BrowserPrefs.properties
new file mode 100644
index 0000000..8a9bf91
--- /dev/null
+++ b/source/edu/stanford/ejalbert/browserprefui/BrowserPrefs.properties
@@ -0,0 +1,26 @@
+# ************************************************
+# Copyright 2006 Jeff Chapman
+
+# This file is part of BrowserLauncher2.
+
+# BrowserLauncher2 is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+# BrowserLauncher2 is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public License
+# along with BrowserLauncher2; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+# ************************************************/
+# $Id: BrowserPrefs.properties,v 1.1 2006/09/26 19:40:41 jchapman0 Exp $
+
+dialog.title=Browser Preference
+
+dialog.bttn.ok=OK
+dialog.bttn.cancel=Cancel
diff --git a/source/edu/stanford/ejalbert/exception/BrowserLaunchingExecutionException.java b/source/edu/stanford/ejalbert/exception/BrowserLaunchingExecutionException.java
new file mode 100644
index 0000000..6c12d7f
--- /dev/null
+++ b/source/edu/stanford/ejalbert/exception/BrowserLaunchingExecutionException.java
@@ -0,0 +1,40 @@
+/************************************************
+ Copyright 2004,2006 Markus Gebhard, Jeff Chapman
+
+ This file is part of BrowserLauncher2.
+
+ BrowserLauncher2 is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ BrowserLauncher2 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with BrowserLauncher2; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ ************************************************/
+// $Id: BrowserLaunchingExecutionException.java,v 1.2 2006/03/23 20:30:50 jchapman0 Exp $
+package edu.stanford.ejalbert.exception;
+
+/**
+ * Exception thrown if there is problem during the attempt to launch
+ * a browser.
+ *
+ * @author Markus Gebhard
+ */
+public class BrowserLaunchingExecutionException
+ extends Exception {
+
+ public BrowserLaunchingExecutionException(Throwable cause) {
+ super(cause);
+ }
+
+ public BrowserLaunchingExecutionException(String message) {
+ super(message);
+ }
+}
diff --git a/source/edu/stanford/ejalbert/exception/BrowserLaunchingInitializingException.java b/source/edu/stanford/ejalbert/exception/BrowserLaunchingInitializingException.java
new file mode 100644
index 0000000..e1f73fa
--- /dev/null
+++ b/source/edu/stanford/ejalbert/exception/BrowserLaunchingInitializingException.java
@@ -0,0 +1,39 @@
+/************************************************
+ Copyright 2004,2006 Markus Gebhard, Jeff Chapman
+
+ This file is part of BrowserLauncher2.
+
+ BrowserLauncher2 is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ BrowserLauncher2 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with BrowserLauncher2; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ ************************************************/
+// $Id: BrowserLaunchingInitializingException.java,v 1.2 2006/03/23 20:30:50 jchapman0 Exp $
+package edu.stanford.ejalbert.exception;
+
+/**
+ * Exception thrown if there is a problem during initialization.
+ *
+ * @author Markus Gebhard
+ */
+public class BrowserLaunchingInitializingException
+ extends Exception {
+
+ public BrowserLaunchingInitializingException(Exception cause) {
+ super(cause);
+ }
+
+ public BrowserLaunchingInitializingException(String message) {
+ super(message);
+ }
+}
diff --git a/source/edu/stanford/ejalbert/exception/UnsupportedOperatingSystemException.java b/source/edu/stanford/ejalbert/exception/UnsupportedOperatingSystemException.java
new file mode 100644
index 0000000..71e9308
--- /dev/null
+++ b/source/edu/stanford/ejalbert/exception/UnsupportedOperatingSystemException.java
@@ -0,0 +1,40 @@
+/************************************************
+ Copyright 2004,2006 Markus Gebhard, Jeff Chapman
+
+ This file is part of BrowserLauncher2.
+
+ BrowserLauncher2 is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ BrowserLauncher2 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with BrowserLauncher2; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ ************************************************/
+// $Id: UnsupportedOperatingSystemException.java,v 1.2 2006/03/23 20:30:50 jchapman0 Exp $
+package edu.stanford.ejalbert.exception;
+
+/**
+ * Exception thrown when the Operating System is not supported by
+ * the browser launcher project.
+ *
+ * @author Markus Gebhard
+ */
+public class UnsupportedOperatingSystemException
+ extends Exception {
+
+ public UnsupportedOperatingSystemException(String message) {
+ super(message);
+ }
+
+ public UnsupportedOperatingSystemException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/source/edu/stanford/ejalbert/exceptionhandler/BrowserLauncherDefaultErrorHandler.java b/source/edu/stanford/ejalbert/exceptionhandler/BrowserLauncherDefaultErrorHandler.java
new file mode 100644
index 0000000..212b45b
--- /dev/null
+++ b/source/edu/stanford/ejalbert/exceptionhandler/BrowserLauncherDefaultErrorHandler.java
@@ -0,0 +1,44 @@
+/************************************************
+ Copyright 2005 Jeff Chapman
+
+ This file is part of BrowserLauncher2.
+
+ BrowserLauncher2 is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ BrowserLauncher2 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with BrowserLauncher2; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ ************************************************/
+// $Id: BrowserLauncherDefaultErrorHandler.java,v 1.1 2005/02/03 00:58:23 jchapman0 Exp $
+package edu.stanford.ejalbert.exceptionhandler;
+
+/**
+ * The default implementation for BrowserLauncherErrorHandler. It simply
+ * prints a stack trace to the console.
+ *
+ * @author Jeff Chapman
+ */
+public class BrowserLauncherDefaultErrorHandler
+ implements BrowserLauncherErrorHandler {
+
+ public BrowserLauncherDefaultErrorHandler() {
+ }
+
+ /**
+ * Handles exception by printing a stack trace to the console.
+ *
+ * @param ex Exception
+ */
+ public void handleException(Exception ex) {
+ ex.printStackTrace();
+ }
+}
diff --git a/source/edu/stanford/ejalbert/exceptionhandler/BrowserLauncherErrorHandler.java b/source/edu/stanford/ejalbert/exceptionhandler/BrowserLauncherErrorHandler.java
new file mode 100644
index 0000000..5a419c9
--- /dev/null
+++ b/source/edu/stanford/ejalbert/exceptionhandler/BrowserLauncherErrorHandler.java
@@ -0,0 +1,41 @@
+/************************************************
+ Copyright 2005 Jeff Chapman
+
+ This file is part of BrowserLauncher2.
+
+ BrowserLauncher2 is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ BrowserLauncher2 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with BrowserLauncher2; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ ************************************************/
+// $Id: BrowserLauncherErrorHandler.java,v 1.1 2005/02/03 00:58:23 jchapman0 Exp $
+package edu.stanford.ejalbert.exceptionhandler;
+
+/**
+ * This is an interface to be used by the BrowserLauncherRunner for handling
+ * exceptions. Applications should implement this interface to handle
+ * exceptions in an application specific manner.
+ *
+ * @author Jeff Chapman
+ */
+public interface BrowserLauncherErrorHandler {
+
+ /**
+ * Takes an exception and does something with it. Usually the implementing
+ * class will want to log the exception or display some information about
+ * it to the user.
+ *
+ * @param ex Exception
+ */
+ public void handleException(Exception ex);
+}
diff --git a/source/edu/stanford/ejalbert/launching/BrowserDescription.java b/source/edu/stanford/ejalbert/launching/BrowserDescription.java
new file mode 100644
index 0000000..04a63ad
--- /dev/null
+++ b/source/edu/stanford/ejalbert/launching/BrowserDescription.java
@@ -0,0 +1,45 @@
+/************************************************
+ Copyright 2006 Jeff Chapman
+
+ This file is part of BrowserLauncher2.
+
+ BrowserLauncher2 is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ BrowserLauncher2 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with BrowserLauncher2; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ ************************************************/
+// $Id: BrowserDescription.java,v 1.1 2006/03/23 20:27:29 jchapman0 Exp $
+package edu.stanford.ejalbert.launching;
+
+/**
+ * Interface to general information about a browser.
+ *
+ * @author Jeff Chapman
+ * @version 1.0
+ */
+public interface BrowserDescription {
+
+ /**
+ * Returns browser display name.
+ *
+ * @returns String
+ */
+ public String getBrowserDisplayName();
+
+ /**
+ * Returns name of executable.
+ *
+ * @returns String
+ */
+ public String getBrowserApplicationName();
+}
diff --git a/source/edu/stanford/ejalbert/launching/BrowserLaunchingFactory.java b/source/edu/stanford/ejalbert/launching/BrowserLaunchingFactory.java
new file mode 100644
index 0000000..6d6ec21
--- /dev/null
+++ b/source/edu/stanford/ejalbert/launching/BrowserLaunchingFactory.java
@@ -0,0 +1,127 @@
+/************************************************
+ Copyright 2004,2005,2006,2007 Markus Gebhard, Jeff Chapman
+
+ This file is part of BrowserLauncher2.
+
+ BrowserLauncher2 is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ BrowserLauncher2 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with BrowserLauncher2; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ ************************************************/
+// $Id: BrowserLaunchingFactory.java,v 1.7 2007/08/27 14:14:10 jchapman0 Exp $
+package edu.stanford.ejalbert.launching;
+
+import edu.stanford.ejalbert.exception.UnsupportedOperatingSystemException;
+import edu.stanford.ejalbert.launching.macos.MacOs2_0BrowserLaunching;
+import edu.stanford.ejalbert.launching.macos.MacOs2_1BrowserLaunching;
+import edu.stanford.ejalbert.launching.macos.MacOs3_0BrowserLaunching;
+import edu.stanford.ejalbert.launching.macos.MacOs3_1BrowserLaunching;
+import edu.stanford.ejalbert.launching.misc.SunOSBrowserLaunching;
+import edu.stanford.ejalbert.launching.misc.UnixNetscapeBrowserLaunching;
+import edu.stanford.ejalbert.launching.windows.WindowsBrowserLaunching;
+import net.sf.wraplog.AbstractLogger;
+
+/**
+ * Factory for determining the OS and returning the appropriate version
+ * of IBrowserLaunching. The factory uses
+ * {@link System#getProperty(String) System.getProperty("os.name")} to
+ * determine the OS.
+ *
+ * @author Markus Gebhard
+ */
+public class BrowserLaunchingFactory {
+
+ /**
+ * Analyzes the name of the underlying operating system
+ * based on the "os.name" system property and returns
+ * the IBrowserLaunching version appropriate for the
+ * O/S.
+ *
+ * @param logger AbstractLogger
+ * @return IBrowserLaunching
+ * @throws UnsupportedOperatingSystemException
+ */
+ public static IBrowserLaunching createSystemBrowserLaunching(
+ AbstractLogger logger)
+ throws UnsupportedOperatingSystemException {
+ String osName = System.getProperty("os.name");
+ if (osName.startsWith("Mac OS")) {
+ logger.info("Mac OS");
+ String mrjVersion = System.getProperty("mrj.version");
+ String majorMRJVersion = mrjVersion.substring(0, 3);
+ try {
+ double version = Double.valueOf(majorMRJVersion).doubleValue();
+ logger.info("version=" + Double.toString(version));
+ if (version == 2) {
+ return new MacOs2_0BrowserLaunching();
+ }
+ else if (version >= 2.1 && version < 3) {
+ // Assume that all 2.x versions of MRJ work the same. MRJ 2.1 actually
+ // works via Runtime.exec() and 2.2 supports that but has an openURL() method
+ // as well that we currently ignore.
+ return new MacOs2_1BrowserLaunching();
+ }
+ else if (version == 3.0) {
+ return new MacOs3_0BrowserLaunching();
+ }
+ else if (version >= 3.1) {
+ // Assume that all 3.1 and later versions of MRJ work the same.
+ return new MacOs3_1BrowserLaunching();
+ }
+ else {
+ throw new UnsupportedOperatingSystemException(
+ "Unsupported MRJ version: " + version);
+ }
+ }
+ catch (NumberFormatException nfe) {
+ throw new UnsupportedOperatingSystemException(
+ "Invalid MRJ version: " + mrjVersion);
+ }
+ }
+ else if (osName.startsWith("Windows")) {
+ logger.info("Windows OS");
+ if (osName.indexOf("9") != -1 ||
+ osName.indexOf("Windows Me") != -1) {
+ return new WindowsBrowserLaunching(
+ logger,
+ WindowsBrowserLaunching.WINKEY_WIN9X);
+ }
+ else if(osName.indexOf("Vista") != -1) {
+ return new WindowsBrowserLaunching(
+ logger,
+ WindowsBrowserLaunching.WINKEY_WINVISTA);
+ }
+ else if (osName.indexOf("2000") != -1 ||
+ osName.indexOf("XP") != -1) {
+ return new WindowsBrowserLaunching(
+ logger,
+ WindowsBrowserLaunching.WINKEY_WIN2000);
+ }
+ else {
+ return new WindowsBrowserLaunching(
+ logger,
+ WindowsBrowserLaunching.WINKEY_WINNT);
+ }
+ }
+ else if (osName.startsWith("SunOS")) {
+ logger.info("SunOS");
+ return new SunOSBrowserLaunching(logger);
+ }
+ else {
+ logger.info("Unix-type OS");
+ return new UnixNetscapeBrowserLaunching(
+ logger,
+ UnixNetscapeBrowserLaunching.CONFIGFILE_LINUX_UNIX);
+ }
+ }
+}
diff --git a/source/edu/stanford/ejalbert/launching/IBrowserLaunching.java b/source/edu/stanford/ejalbert/launching/IBrowserLaunching.java
new file mode 100644
index 0000000..27aab48
--- /dev/null
+++ b/source/edu/stanford/ejalbert/launching/IBrowserLaunching.java
@@ -0,0 +1,177 @@
+/************************************************
+ Copyright 2004,2005,2006,2007 Markus Gebhard, Jeff Chapman
+
+ This file is part of BrowserLauncher2.
+
+ BrowserLauncher2 is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ BrowserLauncher2 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with BrowserLauncher2; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ ************************************************/
+// $Id: IBrowserLaunching.java,v 1.9 2007/08/27 14:15:20 jchapman0 Exp $
+package edu.stanford.ejalbert.launching;
+
+import java.util.List;
+
+import edu.stanford.ejalbert.exception.BrowserLaunchingExecutionException;
+import edu.stanford.ejalbert.exception.BrowserLaunchingInitializingException;
+import edu.stanford.ejalbert.exception.UnsupportedOperatingSystemException;
+
+/**
+ * Main interface to the Browser Launching methods.
+ *
+ * @author Markus Gebhard
+ */
+public interface IBrowserLaunching {
+ /**
+ * Key to system property containing name of users
+ * preferred browser.
+ */
+ public static final String BROWSER_SYSTEM_PROPERTY =
+ "edu.stanford.ejalbert.preferred.browser";
+ /**
+ * Key to system property that controls how browsers are discovered
+ * when running on a Windows O/S.
+ * <p>
+ * The values are registry and disk.
+ */
+ public static final String WINDOWS_BROWSER_DISC_POLICY_PROPERTY =
+ "win.browser.disc.policy";
+ /**
+ * Value associated with WINDOWS_BROWSER_DISC_POLICY_PROPERTY.
+ */
+ public static final String WINDOWS_BROWSER_DISC_POLICY_DISK = "disk";
+ /**
+ * Value associated with WINDOWS_BROWSER_DISC_POLICY_PROPERTY.
+ */
+ public static final String WINDOWS_BROWSER_DISC_POLICY_REGISTRY = "registry";
+ /**
+ * property file key for delimiter character used in other properties.
+ */
+ public static final String PROP_KEY_DELIMITER = "delimchar";
+ /**
+ * prefix used for property file keys that define a browser
+ */
+ public static final String PROP_KEY_BROWSER_PREFIX = "browser.";
+ /**
+ * http protocol
+ */
+ public static final String PROTOCOL_HTTP = "http";
+ /**
+ * file protocol
+ */
+ public static final String PROTOCOL_FILE = "file";
+ /**
+ * mailto protocol
+ */
+ public static final String PROTOCOL_MAILTO = "mailto";
+ /**
+ * Identifier for the system's default browser.
+ */
+ public static final String BROWSER_DEFAULT = "Default";
+
+ /**
+ * Performs any initialization needed for the particular O/S.
+ *
+ * @throws BrowserLaunchingInitializingException
+ */
+ public void initialize()
+ throws BrowserLaunchingInitializingException;
+
+ /**
+ * Opens the passed url in the system's default browser.
+ *
+ * @param urlString String
+ * @throws UnsupportedOperatingSystemException
+ * @throws BrowserLaunchingExecutionException
+ * @throws BrowserLaunchingInitializingException
+ */
+ public void openUrl(String urlString)
+ throws UnsupportedOperatingSystemException,
+ BrowserLaunchingExecutionException,
+ BrowserLaunchingInitializingException;
+
+ /**
+ * Allows user to target a specific browser. The names of
+ * potential browsers can be accessed via the
+ * {@link #getBrowserList() getBrowserList} method.
+ * <p>
+ * If the call to the requested browser fails, the code will
+ * fail over to the default browser.
+ *
+ * @param browser String
+ * @param urlString String
+ * @throws UnsupportedOperatingSystemException
+ * @throws BrowserLaunchingExecutionException
+ * @throws BrowserLaunchingInitializingException
+ */
+ public void openUrl(String browser,
+ String urlString)
+ throws UnsupportedOperatingSystemException,
+ BrowserLaunchingExecutionException,
+ BrowserLaunchingInitializingException;
+
+ /**
+ * Allows user to target several browsers. The names of
+ * potential browsers can be accessed via the
+ * {@link #getBrowserList() getBrowserList} method.
+ * <p>
+ * The browsers from the list will be tried in order
+ * (first to last) until one of the calls succeeds. If
+ * all the calls to the requested browsers fail, the code
+ * will fail over to the default browser.
+ *
+ * @param browsers List
+ * @param urlString String
+ * @throws UnsupportedOperatingSystemException
+ * @throws BrowserLaunchingExecutionException
+ * @throws BrowserLaunchingInitializingException
+ */
+ public void openUrl(List browsers,
+ String urlString)
+ throws UnsupportedOperatingSystemException,
+ BrowserLaunchingExecutionException,
+ BrowserLaunchingInitializingException;
+
+ /**
+ * Returns a list of browsers to be used for browser targetting.
+ * This list will always contain at least one item:
+ * {@link #BROWSER_DEFAULT BROWSER_DEFAULT}.
+ *
+ * @return List
+ */
+ public List getBrowserList();
+
+ /**
+ * Returns the policy used for opening a url in a browser.
+ * <p>
+ * If the policy is true, an attempt will be made to force the
+ * url to be opened in a new instance (window) of the
+ * browser.
+ * <p>
+ * If the policy is false, the url may open in a new window or
+ * a new tab.
+ * <p>
+ * Results will vary based on the O/S and browser being targetted.
+ *
+ * @return boolean
+ */
+ public boolean getNewWindowPolicy();
+
+ /**
+ * Sets the policy used for opening a url in a browser.
+ *
+ * @param forceNewWindow boolean
+ */
+ public void setNewWindowPolicy(boolean forceNewWindow);
+}
diff --git a/source/edu/stanford/ejalbert/launching/macos/MacOs2_0BrowserLaunching.java b/source/edu/stanford/ejalbert/launching/macos/MacOs2_0BrowserLaunching.java
new file mode 100644
index 0000000..e77950d
--- /dev/null
+++ b/source/edu/stanford/ejalbert/launching/macos/MacOs2_0BrowserLaunching.java
@@ -0,0 +1,153 @@
+/************************************************
+ Copyright 2004,2006 Markus Gebhard, Jeff Chapman
+
+ This file is part of BrowserLauncher2.
+
+ BrowserLauncher2 is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ BrowserLauncher2 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with BrowserLauncher2; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ ************************************************/
+// $Id: MacOs2_0BrowserLaunching.java,v 1.3 2006/04/11 13:36:48 jchapman0 Exp $
+package edu.stanford.ejalbert.launching.macos;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+import edu.stanford.ejalbert.exception.BrowserLaunchingExecutionException;
+import edu.stanford.ejalbert.exception.BrowserLaunchingInitializingException;
+import edu.stanford.ejalbert.exception.UnsupportedOperatingSystemException;
+import edu.stanford.ejalbert.launching.IBrowserLaunching;
+
+/**
+ * @author Markus Gebhard
+ */
+public class MacOs2_0BrowserLaunching
+ extends MacOsBrowserLaunching {
+
+ /** The name for the AppleEvent type corresponding to a GetURL event. */
+ private static final String GURL_EVENT = "GURL";
+
+ private Class aeDescClass;
+ private Constructor aeTargetConstructor;
+ private Constructor appleEventConstructor;
+ private Constructor aeDescConstructor;
+ private Method makeOSType;
+ private Method putParameter;
+ private Method sendNoReply;
+ private Integer keyDirectObject;
+ private Integer kAutoGenerateReturnID;
+ private Integer kAnyTransactionID;
+
+ public void initialize()
+ throws BrowserLaunchingInitializingException {
+ try {
+ Class aeTargetClass = Class.forName("com.apple.MacOS.AETarget");
+ Class osUtilsClass = Class.forName("com.apple.MacOS.OSUtils");
+ Class appleEventClass = Class.forName("com.apple.MacOS.AppleEvent");
+ Class aeClass = Class.forName("com.apple.MacOS.ae");
+ aeDescClass = Class.forName("com.apple.MacOS.AEDesc");
+
+ aeTargetConstructor = aeTargetClass.getDeclaredConstructor(new
+ Class[] {int.class});
+ appleEventConstructor =
+ appleEventClass.getDeclaredConstructor(
+ new Class[] {int.class, int.class, aeTargetClass, int.class, int.class});
+ aeDescConstructor = aeDescClass.getDeclaredConstructor(new Class[] {
+ String.class});
+
+ makeOSType = osUtilsClass.getDeclaredMethod("makeOSType",
+ new Class[] {String.class});
+ putParameter = appleEventClass.getDeclaredMethod("putParameter",
+ new Class[] {int.class, aeDescClass});
+ sendNoReply = appleEventClass.getDeclaredMethod("sendNoReply",
+ new Class[] {
+ });
+
+ Field keyDirectObjectField = aeClass.getDeclaredField(
+ "keyDirectObject");
+ keyDirectObject = (Integer) keyDirectObjectField.get(null);
+ Field autoGenerateReturnIDField = appleEventClass.getDeclaredField(
+ "kAutoGenerateReturnID");
+ kAutoGenerateReturnID = (Integer) autoGenerateReturnIDField.get(null);
+ Field anyTransactionIDField = appleEventClass.getDeclaredField(
+ "kAnyTransactionID");
+ kAnyTransactionID = (Integer) anyTransactionIDField.get(null);
+ }
+ catch (Exception cnfe) {
+ throw new BrowserLaunchingInitializingException(cnfe);
+ }
+ }
+
+ private Object getBrowser()
+ throws BrowserLaunchingInitializingException {
+ try {
+ Integer finderCreatorCode = (Integer) makeOSType.invoke(null,
+ new Object[] {FINDER_CREATOR});
+ Object aeTarget = aeTargetConstructor.newInstance(new Object[] {
+ finderCreatorCode});
+ Integer gurlType = (Integer) makeOSType.invoke(null,
+ new Object[] {GURL_EVENT});
+ Object appleEvent =
+ appleEventConstructor.newInstance(
+ new Object[] {gurlType, gurlType, aeTarget,
+ kAutoGenerateReturnID, kAnyTransactionID});
+ // Don't set browser = appleEvent because then the next time we call
+ // locateBrowser(), we'll get the same AppleEvent, to which we'll already have
+ // added the relevant parameter. Instead, regenerate the AppleEvent every time.
+ // There's probably a way to do this better; if any has any ideas, please let
+ // me know.
+ return appleEvent;
+ }
+ catch (Exception e) {
+ throw new BrowserLaunchingInitializingException(e);
+ }
+ }
+
+ public void openUrl(String urlString)
+ throws UnsupportedOperatingSystemException,
+ BrowserLaunchingExecutionException,
+ BrowserLaunchingInitializingException {
+ Object browser = getBrowser();
+ Object aeDesc = null;
+ try {
+ aeDesc = aeDescConstructor.newInstance(new Object[] {urlString});
+ putParameter.invoke(browser, new Object[] {keyDirectObject, aeDesc});
+ sendNoReply.invoke(browser, new Object[] {
+ });
+ }
+ catch (Exception e) {
+ throw new BrowserLaunchingExecutionException(e);
+ }
+ finally {
+ //TODO Oct 10, 2003 (Markus Gebhard): Unnecessary, because local variables - isn't it?
+ aeDesc = null; // Encourage it to get disposed if it was created
+ browser = null; // Ditto
+ }
+ }
+
+ /**
+ * Returns a list of browsers to be used for browser targetting.
+ * This list will always contain at least one item--the BROWSER_DEFAULT.
+ *
+ * @return List
+ */
+ public List getBrowserList() {
+ List browserList = new ArrayList(1);
+ browserList.add(IBrowserLaunching.BROWSER_DEFAULT);
+ return browserList;
+ }
+}
diff --git a/source/edu/stanford/ejalbert/launching/macos/MacOs2_1BrowserLaunching.java b/source/edu/stanford/ejalbert/launching/macos/MacOs2_1BrowserLaunching.java
new file mode 100644
index 0000000..82e80db
--- /dev/null
+++ b/source/edu/stanford/ejalbert/launching/macos/MacOs2_1BrowserLaunching.java
@@ -0,0 +1,144 @@
+/************************************************
+ Copyright 2004,2006 Markus Gebhard, Jeff Chapman
+
+ This file is part of BrowserLauncher2.
+
+ BrowserLauncher2 is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ BrowserLauncher2 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with BrowserLauncher2; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ ************************************************/
+// $Id: MacOs2_1BrowserLaunching.java,v 1.3 2006/04/11 13:36:48 jchapman0 Exp $
+package edu.stanford.ejalbert.launching.macos;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+import edu.stanford.ejalbert.exception.BrowserLaunchingExecutionException;
+import edu.stanford.ejalbert.exception.BrowserLaunchingInitializingException;
+import edu.stanford.ejalbert.exception.UnsupportedOperatingSystemException;
+import edu.stanford.ejalbert.launching.IBrowserLaunching;
+
+/**
+ * @author Markus Gebhard
+ */
+public class MacOs2_1BrowserLaunching
+ extends MacOsBrowserLaunching implements IBrowserLaunching {
+
+ /**
+ * The file type of the Finder on a Macintosh. Hardcoding "Finder" would keep non-U.S. English
+ * systems from working properly.
+ */
+ private static final String FINDER_TYPE = "FNDR";
+
+ private Object kSystemFolderType;
+ private Method findFolder;
+ private Method getFileCreator;
+ private Method getFileType;
+
+ private String browser;
+
+ public void initialize()
+ throws BrowserLaunchingInitializingException {
+ try {
+ Class mrjFileUtilsClass = Class.forName(
+ "com.apple.mrj.MRJFileUtils");
+ Class mrjOSTypeClass = Class.forName("com.apple.mrj.MRJOSType");
+ Field systemFolderField = mrjFileUtilsClass.getDeclaredField(
+ "kSystemFolderType");
+ kSystemFolderType = systemFolderField.get(null);
+ findFolder = mrjFileUtilsClass.getDeclaredMethod("findFolder",
+ new Class[] {mrjOSTypeClass});
+ getFileCreator = mrjFileUtilsClass.getDeclaredMethod(
+ "getFileCreator", new Class[] {File.class});
+ getFileType = mrjFileUtilsClass.getDeclaredMethod("getFileType",
+ new Class[] {File.class});
+ }
+ catch (Exception e) {
+ throw new BrowserLaunchingInitializingException(e);
+ }
+ }
+
+ private String getBrowser()
+ throws BrowserLaunchingInitializingException {
+ if (browser != null) {
+ return browser;
+ }
+
+ File systemFolder;
+ try {
+ systemFolder = (File) findFolder.invoke(null,
+ new Object[] {kSystemFolderType});
+ }
+ catch (Exception e) {
+ throw new BrowserLaunchingInitializingException(e);
+ }
+ String[] systemFolderFiles = systemFolder.list();
+ // Avoid a FilenameFilter because that can't be stopped mid-list
+ for (int i = 0; i < systemFolderFiles.length; i++) {
+ try {
+ File file = new File(systemFolder, systemFolderFiles[i]);
+ if (!file.isFile()) {
+ continue;
+ }
+ // We're looking for a file with a creator code of 'MACS' and
+ // a type of 'FNDR'. Only requiring the type results in non-Finder
+ // applications being picked up on certain Mac OS 9 systems,
+ // especially German ones, and sending a GURL event to those
+ // applications results in a logout under Multiple Users.
+ Object fileType = getFileType.invoke(null, new Object[] {file});
+ if (FINDER_TYPE.equals(fileType.toString())) {
+ Object fileCreator = getFileCreator.invoke(null,
+ new Object[] {file});
+ if (FINDER_CREATOR.equals(fileCreator.toString())) {
+ browser = file.toString(); // Actually the Finder, but that's OK
+ return browser;
+ }
+ }
+ }
+ catch (Exception e) {
+ throw new BrowserLaunchingInitializingException(e);
+ }
+ }
+ throw new BrowserLaunchingInitializingException("Unable to find finder");
+ }
+
+ public void openUrl(String urlString)
+ throws UnsupportedOperatingSystemException,
+ BrowserLaunchingExecutionException,
+ BrowserLaunchingInitializingException {
+ String browser = getBrowser();
+ try {
+ Runtime.getRuntime().exec(new String[] {browser, urlString});
+ }
+ catch (IOException e) {
+ throw new BrowserLaunchingExecutionException(e);
+ }
+ }
+
+ /**
+ * Returns a list of browsers to be used for browser targetting.
+ * This list will always contain at least one item--the BROWSER_DEFAULT.
+ *
+ * @return List
+ */
+ public List getBrowserList() {
+ List browserList = new ArrayList(1);
+ browserList.add(IBrowserLaunching.BROWSER_DEFAULT);
+ return browserList;
+ }
+}
diff --git a/source/edu/stanford/ejalbert/launching/macos/MacOs3_0BrowserLaunching.java b/source/edu/stanford/ejalbert/launching/macos/MacOs3_0BrowserLaunching.java
new file mode 100644
index 0000000..ab1a339
--- /dev/null
+++ b/source/edu/stanford/ejalbert/launching/macos/MacOs3_0BrowserLaunching.java
@@ -0,0 +1,110 @@
+/************************************************
+ Copyright 2004,2006 Markus Gebhard, Jeff Chapman
+
+ This file is part of BrowserLauncher2.
+
+ BrowserLauncher2 is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ BrowserLauncher2 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with BrowserLauncher2; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ ************************************************/
+// $Id: MacOs3_0BrowserLaunching.java,v 1.3 2006/04/11 13:36:48 jchapman0 Exp $
+package edu.stanford.ejalbert.launching.macos;
+
+import java.lang.reflect.Constructor;
+import java.util.ArrayList;
+import java.util.List;
+
+import edu.stanford.ejalbert.BrowserLauncher;
+import edu.stanford.ejalbert.exception.BrowserLaunchingExecutionException;
+import edu.stanford.ejalbert.exception.BrowserLaunchingInitializingException;
+import edu.stanford.ejalbert.exception.UnsupportedOperatingSystemException;
+import edu.stanford.ejalbert.launching.IBrowserLaunching;
+
+/**
+ * @author Markus Gebhard
+ */
+public class MacOs3_0BrowserLaunching
+ extends MacOsBrowserLaunching {
+
+ public void initialize()
+ throws BrowserLaunchingInitializingException {
+ //TODO Oct 10, 2003 (Markus Gebhard): Can anyone explain what this code is for??
+ try {
+ Class linker = Class.forName("com.apple.mrj.jdirect.Linker");
+ Constructor constructor = linker.getConstructor(new Class[] {Class.class});
+ Object linkage = constructor.newInstance(new Object[] {
+ BrowserLauncher.class});
+ }
+ catch (Exception e) {
+ throw new BrowserLaunchingInitializingException(e);
+ }
+ }
+
+ public void openUrl(String urlString)
+ throws UnsupportedOperatingSystemException,
+ BrowserLaunchingExecutionException,
+ BrowserLaunchingInitializingException {
+ int[] instance = new int[1];
+ int result = ICStart(instance, 0);
+ if (result == 0) {
+ int[] selectionStart = new int[] {0};
+ byte[] urlBytes = urlString.getBytes();
+ int[] selectionEnd = new int[] {urlBytes.length};
+ result =
+ ICLaunchURL(instance[0], new byte[] {0}, urlBytes,
+ urlBytes.length, selectionStart, selectionEnd);
+ if (result == 0) {
+ // Ignore the return value; the URL was launched successfully
+ // regardless of what happens here.
+ ICStop(instance);
+ }
+ else {
+ throw new BrowserLaunchingExecutionException(
+ "Unable to launch URL: " + result);
+ }
+ }
+ else {
+ throw new BrowserLaunchingExecutionException(
+ "Unable to create an Internet Config instance: " + result);
+ }
+ }
+
+ /**
+ * Returns a list of browsers to be used for browser targetting.
+ * This list will always contain at least one item--the BROWSER_DEFAULT.
+ *
+ * @return List
+ */
+ public List getBrowserList() {
+ List browserList = new ArrayList(1);
+ browserList.add(IBrowserLaunching.BROWSER_DEFAULT);
+ return browserList;
+ }
+
+ /**
+ * Methods required for Mac OS X. The presence of native methods does not cause
+ * any problems on other platforms.
+ */
+ private native static int ICStart(int[] instance, int signature);
+
+ private native static int ICStop(int[] instance);
+
+ private native static int ICLaunchURL(
+ int instance,
+ byte[] hint,
+ byte[] data,
+ int len,
+ int[] selectionStart,
+ int[] selectionEnd);
+}
diff --git a/source/edu/stanford/ejalbert/launching/macos/MacOs3_1BrowserLaunching.java b/source/edu/stanford/ejalbert/launching/macos/MacOs3_1BrowserLaunching.java
new file mode 100644
index 0000000..bcb5573
--- /dev/null
+++ b/source/edu/stanford/ejalbert/launching/macos/MacOs3_1BrowserLaunching.java
@@ -0,0 +1,76 @@
+/************************************************
+ Copyright 2004,2006 Markus Gebhard, Jeff Chapman
+
+ This file is part of BrowserLauncher2.
+
+ BrowserLauncher2 is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ BrowserLauncher2 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with BrowserLauncher2; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ ************************************************/
+// $Id: MacOs3_1BrowserLaunching.java,v 1.3 2006/04/11 13:36:48 jchapman0 Exp $
+package edu.stanford.ejalbert.launching.macos;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+import edu.stanford.ejalbert.exception.BrowserLaunchingExecutionException;
+import edu.stanford.ejalbert.exception.BrowserLaunchingInitializingException;
+import edu.stanford.ejalbert.exception.UnsupportedOperatingSystemException;
+import edu.stanford.ejalbert.launching.IBrowserLaunching;
+
+/**
+ * @author Markus Gebhard
+ */
+public class MacOs3_1BrowserLaunching
+ extends MacOsBrowserLaunching {
+ private Method openURL;
+
+ public void initialize()
+ throws BrowserLaunchingInitializingException {
+ try {
+ Class mrjFileUtilsClass = Class.forName(
+ "com.apple.mrj.MRJFileUtils");
+ openURL = mrjFileUtilsClass.getDeclaredMethod("openURL",
+ new Class[] {String.class});
+ }
+ catch (Exception e) {
+ throw new BrowserLaunchingInitializingException(e);
+ }
+ }
+
+ public void openUrl(String urlString)
+ throws UnsupportedOperatingSystemException,
+ BrowserLaunchingExecutionException,
+ BrowserLaunchingInitializingException {
+ try {
+ openURL.invoke(null, new Object[] {urlString});
+ }
+ catch (Exception e) {
+ throw new BrowserLaunchingExecutionException(e);
+ }
+ }
+
+ /**
+ * Returns a list of browsers to be used for browser targetting.
+ * This list will always contain at least one item--the BROWSER_DEFAULT.
+ *
+ * @return List
+ */
+ public List getBrowserList() {
+ List browserList = new ArrayList(1);
+ browserList.add(IBrowserLaunching.BROWSER_DEFAULT);
+ return browserList;
+ }
+}
diff --git a/source/edu/stanford/ejalbert/launching/macos/MacOsBrowserLaunching.java b/source/edu/stanford/ejalbert/launching/macos/MacOsBrowserLaunching.java
new file mode 100644
index 0000000..f3c2c59
--- /dev/null
+++ b/source/edu/stanford/ejalbert/launching/macos/MacOsBrowserLaunching.java
@@ -0,0 +1,113 @@
+/************************************************
+ Copyright 2004,2006 Markus Gebhard, Jeff Chapman
+
+ This file is part of BrowserLauncher2.
+
+ BrowserLauncher2 is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ BrowserLauncher2 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with BrowserLauncher2; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ ************************************************/
+// $Id: MacOsBrowserLaunching.java,v 1.3 2006/09/11 20:38:13 jchapman0 Exp $
+package edu.stanford.ejalbert.launching.macos;
+
+import java.util.List;
+
+import edu.stanford.ejalbert.exception.BrowserLaunchingExecutionException;
+import edu.stanford.ejalbert.exception.BrowserLaunchingInitializingException;
+import edu.stanford.ejalbert.exception.UnsupportedOperatingSystemException;
+import edu.stanford.ejalbert.launching.IBrowserLaunching;
+
+/**
+ * @author Markus Gebhard
+ */
+public abstract class MacOsBrowserLaunching
+ implements IBrowserLaunching {
+ /**
+ * new window policy to apply when opening a url. If true,
+ * try to force url into a new browser instance/window.
+ */
+ private boolean forceNewWindow = false;
+
+ /**
+ * The creator code of the Finder on a Macintosh, which is needed to send AppleEvents to the
+ * application.
+ */
+ protected static final String FINDER_CREATOR = "MACS";
+
+ /* ---------------- from IBrowserLaunching ---------------- */
+
+ /**
+ * Falls through to non-targetted openUrl method. Browser
+ * targetting has not been implemented for the Mac.
+ *
+ * @param browser String
+ * @param urlString String
+ * @throws UnsupportedOperatingSystemException
+ * @throws BrowserLaunchingExecutionException
+ * @throws BrowserLaunchingInitializingException
+ */
+ public void openUrl(String browser,
+ String urlString)
+ throws UnsupportedOperatingSystemException,
+ BrowserLaunchingExecutionException,
+ BrowserLaunchingInitializingException {
+ openUrl(urlString);
+ }
+
+ /**
+ * Falls through to non-targetted openUrl method. Browser
+ * targetting has not been implemented for the Mac.
+ *
+ * @param browsers List
+ * @param urlString String
+ * @throws UnsupportedOperatingSystemException
+ * @throws BrowserLaunchingExecutionException
+ * @throws BrowserLaunchingInitializingException
+ */
+ public void openUrl(List browsers,
+ String urlString)
+ throws UnsupportedOperatingSystemException,
+ BrowserLaunchingExecutionException,
+ BrowserLaunchingInitializingException {
+ openUrl(urlString);
+ }
+
+ /**
+ * Returns the policy used for opening a url in a browser.
+ * <p>
+ * If the policy is true, an attempt will be made to force the
+ * url to be opened in a new instance (window) of the
+ * browser.
+ * <p>
+ * If the policy is false, the url may open in a new window or
+ * a new tab.
+ * <p>
+ * This is not supported on the Mac OS.
+ *
+ * @return boolean
+ */
+ public boolean getNewWindowPolicy() {
+ return forceNewWindow;
+ }
+
+ /**
+ * Sets the policy used for opening a url in a browser.
+ * This is not supported on the Mac OS.
+ *
+ * @param forceNewWindow boolean
+ */
+ public void setNewWindowPolicy(boolean forceNewWindow) {
+ this.forceNewWindow = forceNewWindow;
+ }
+}
diff --git a/source/edu/stanford/ejalbert/launching/misc/StandardUnixBrowser.java b/source/edu/stanford/ejalbert/launching/misc/StandardUnixBrowser.java
new file mode 100644
index 0000000..cfe7aa8
--- /dev/null
+++ b/source/edu/stanford/ejalbert/launching/misc/StandardUnixBrowser.java
@@ -0,0 +1,202 @@
+/************************************************
+ Copyright 2004,2005,2006,2007 Jeff Chapman
+
+ This file is part of BrowserLauncher2.
+
+ BrowserLauncher2 is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ BrowserLauncher2 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with BrowserLauncher2; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ ************************************************/
+// $Id: StandardUnixBrowser.java,v 1.8 2007/08/31 15:54:10 jchapman0 Exp $
+package edu.stanford.ejalbert.launching.misc;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+import net.sf.wraplog.AbstractLogger;
+import edu.stanford.ejalbert.launching.utils.LaunchingUtils;
+
+/**
+ * Contains information on a unix browser.
+ */
+class StandardUnixBrowser
+ implements UnixBrowser {
+ /**
+ * name of browser for user display
+ */
+ private final String browserName; // in ctor
+ /**
+ * name of browser executable used to invoke it
+ */
+ private final String browserArgName; // in ctor
+ /**
+ * arguments used to address an already open browser.
+ */
+ private final String argsForOpenBrowser; // in ctor
+ /**
+ * arguments used for starting a new instance of a browser.
+ */
+ private final String argsForStartBrowser; // in ctor
+
+ private final String argsForForcedBrowserWindow; // in ctor
+
+ /**
+ * Splits the config string using the configSep character.
+ * The resulting config items are used to set the
+ * browser display name, the browser executable name, and
+ * the arguments for starting a new browser instance and
+ * addressing an already open browser.
+ *
+ * @param configSep String
+ * @param configStr String
+ */
+ StandardUnixBrowser(String configSep,
+ String configStr) {
+ String[] configItems = configStr.split(configSep, -2);
+ this.browserName = configItems[0];
+ this.browserArgName = configItems[1];
+ this.argsForStartBrowser = configItems[2];
+ this.argsForOpenBrowser = configItems[3];
+ if(configItems.length == 5) {
+ this.argsForForcedBrowserWindow = configItems[4];
+ }
+ else {
+ this.argsForForcedBrowserWindow = configItems[2];
+ }
+ }
+
+ /**
+ * Returns debug information.
+ *
+ * @return String
+ */
+ public String toString() {
+ StringBuffer buf = new StringBuffer();
+ buf.append("display name=");
+ buf.append(browserName);
+ buf.append(" executable name=");
+ buf.append(browserArgName);
+ buf.append(" argsForStartBrowser=");
+ buf.append(argsForStartBrowser);
+ buf.append(" argsForOpenBrowser=");
+ buf.append(argsForOpenBrowser);
+ return buf.toString();
+ }
+
+ /**
+ * Replaces the placeholders <browser> and <url> in the
+ * argsString and splits the resulting string around
+ * space characters.
+ *
+ * @param argsString String
+ * @param urlString String
+ * @return String[]
+ */
+ private String[] getCommandLineArgs(String argsString,
+ String urlString) {
+ argsString = LaunchingUtils.replaceArgs(argsString,
+ browserArgName,
+ urlString);
+ return argsString.split("[ ]");
+ }
+
+ /* --------------------- from BrowserDescription --------------------- */
+
+ /**
+ * Returns the display name for the browser.
+ *
+ * @return String
+ */
+ public String getBrowserDisplayName() {
+ return browserName;
+ }
+
+ /**
+ * Returns the executable name for the browser.
+ *
+ * @return String
+ */
+ public String getBrowserApplicationName() {
+ return browserArgName;
+ }
+
+ /* ------------------------- from UnixBrowser ------------------------ */
+
+ /**
+ * Returns the command line arguments for addressing an already
+ * open browser.
+ *
+ * @param urlString String
+ * @return String[]
+ */
+ public String[] getArgsForOpenBrowser(String urlString) {
+ String argsStartString = argsForOpenBrowser != null &&
+ argsForOpenBrowser.length() > 0 ?
+ argsForOpenBrowser : argsForStartBrowser;
+ return getCommandLineArgs(argsStartString, urlString);
+ }
+
+ /**
+ * Returns the command line arguments for starting a new browser
+ * instance.
+ *
+ * @param urlString String
+ * @return String[]
+ */
+ public String[] getArgsForStartingBrowser(String urlString) {
+ return getCommandLineArgs(argsForStartBrowser, urlString);
+ }
+
+ public String[] getArgsForForcingNewBrowserWindow(String urlString) {
+ return getCommandLineArgs(argsForForcedBrowserWindow, urlString);
+ }
+
+ /**
+ * Returns true if the browser is available, ie which command finds it.
+ *
+ * @param logger AbstractLogger
+ * @return boolean
+ */
+ public boolean isBrowserAvailable(AbstractLogger logger) {
+ boolean isAvailable = false;
+ try {
+ Process process = Runtime.getRuntime().exec(new String[] {"which",
+ browserArgName});
+ InputStream errStream = process.getErrorStream();
+ InputStream inStream = process.getInputStream();
+ BufferedReader errIn
+ = new BufferedReader(new InputStreamReader(errStream));
+ BufferedReader in
+ = new BufferedReader(new InputStreamReader(inStream));
+ String whichOutput = in.readLine();
+ String whichErrOutput = errIn.readLine();
+ in.close();
+ errIn.close();
+ if(whichOutput != null) {
+ logger.debug(whichOutput);
+ }
+ if(whichErrOutput != null) {
+ logger.debug(whichErrOutput);
+ }
+ isAvailable = whichOutput != null &&
+ whichOutput.startsWith("/");
+ }
+ catch (IOException ex) {
+ logger.error("io error executing which command", ex);
+ }
+ return isAvailable;
+ }
+}
diff --git a/source/edu/stanford/ejalbert/launching/misc/SunOSBrowserLaunching.java b/source/edu/stanford/ejalbert/launching/misc/SunOSBrowserLaunching.java
new file mode 100644
index 0000000..57ae413
--- /dev/null
+++ b/source/edu/stanford/ejalbert/launching/misc/SunOSBrowserLaunching.java
@@ -0,0 +1,98 @@
+/************************************************
+ Copyright 2005,2006 Olivier Hochreutiner, Jeff Chapman
+
+ This file is part of BrowserLauncher2.
+
+ BrowserLauncher2 is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ BrowserLauncher2 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with BrowserLauncher2; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ ************************************************/
+// $Id: SunOSBrowserLaunching.java,v 1.3 2006/10/26 20:02:18 jchapman0 Exp $
+package edu.stanford.ejalbert.launching.misc;
+
+import edu.stanford.ejalbert.exception.BrowserLaunchingExecutionException;
+import edu.stanford.ejalbert.exception.BrowserLaunchingInitializingException;
+import edu.stanford.ejalbert.exception.UnsupportedOperatingSystemException;
+import edu.stanford.ejalbert.launching.IBrowserLaunching;
+import net.sf.wraplog.AbstractLogger;
+
+/**
+ * Launches a default browser on SunOS Unix systems using the sdtwebclient
+ * command.
+ *
+ * @author Olivier Hochreutiner
+ */
+public class SunOSBrowserLaunching
+ extends UnixNetscapeBrowserLaunching {
+ /**
+ * config file for SunOS.
+ */
+ public static final String CONFIGFILE_SUNOS =
+ "/edu/stanford/ejalbert/launching/misc/sunOSConfig.properties";
+
+ /**
+ * Passes the logger and config file for SunOS to its
+ * super class.
+ *
+ * @param logger AbstractLogger
+ */
+ public SunOSBrowserLaunching(AbstractLogger logger) {
+ super(logger, CONFIGFILE_SUNOS);
+ }
+
+ /**
+ * Opens a url using the default browser. It uses sdtwebclient
+ * to launch the default browser. The sdtwebclient executable
+ * is mapped to
+ * {@link IBrowserLaunching.BROWSER_DEFAULT IBrowserLaunching.BROWSER_DEFAULT}.
+ *
+ * @param urlString String
+ * @throws BrowserLaunchingExecutionException
+ */
+ public void openUrl(String urlString)
+ throws UnsupportedOperatingSystemException,
+ BrowserLaunchingExecutionException,
+ BrowserLaunchingInitializingException {
+ try {
+ logger.info(urlString);
+ // check system property which may contain user's preferred browser
+ String browserId = System.getProperty(
+ IBrowserLaunching.BROWSER_SYSTEM_PROPERTY,
+ null);
+ StandardUnixBrowser defBrowser = getBrowser(
+ IBrowserLaunching.BROWSER_DEFAULT);
+ if (browserId != null) {
+ logger.info(
+ "browser pref defined in system prop. Failing over to super.openUrl() method");
+ super.openUrl(urlString);
+ }
+ // we should always have a default browser defined for
+ // SunOS but if not, fail over to super class method
+ else if (defBrowser == null) {
+ logger.info(
+ "no default browser defined. Failing over to super.openUrl() method");
+ super.openUrl(urlString);
+ }
+ else {
+ logger.info(defBrowser.getBrowserDisplayName());
+ Process process = Runtime.getRuntime().exec(
+ defBrowser.getArgsForStartingBrowser(urlString));
+ process.waitFor();
+ }
+ }
+ catch (Exception e) {
+ throw new BrowserLaunchingExecutionException(e);
+ }
+ }
+}
diff --git a/source/edu/stanford/ejalbert/launching/misc/UnixBrowser.java b/source/edu/stanford/ejalbert/launching/misc/UnixBrowser.java
new file mode 100644
index 0000000..b8f520f
--- /dev/null
+++ b/source/edu/stanford/ejalbert/launching/misc/UnixBrowser.java
@@ -0,0 +1,61 @@
+/************************************************
+ Copyright 2004,2006 Jeff Chapman
+
+ This file is part of BrowserLauncher2.
+
+ BrowserLauncher2 is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ BrowserLauncher2 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with BrowserLauncher2; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ ************************************************/
+// $Id: UnixBrowser.java,v 1.4 2006/09/11 20:41:55 jchapman0 Exp $
+package edu.stanford.ejalbert.launching.misc;
+
+import edu.stanford.ejalbert.launching.BrowserDescription;
+import net.sf.wraplog.AbstractLogger;
+
+/**
+ * Augments the standard browser description with information
+ * specific to a Unix type browser.
+ */
+public interface UnixBrowser
+ extends BrowserDescription {
+ /**
+ * Returns the command line arguments for addressing an already
+ * open browser.
+ *
+ * @param urlString String
+ * @return String[]
+ */
+ public String[] getArgsForOpenBrowser(String url);
+
+ /**
+ * Returns the command line arguments for starting a new browser
+ * instance.
+ *
+ * @param urlString String
+ * @return String[]
+ */
+ public String[] getArgsForStartingBrowser(String url);
+
+ public String[] getArgsForForcingNewBrowserWindow(String url);
+
+
+ /**
+ * Returns true if the browser is available on the user's system..
+ *
+ * @param logger AbstractLogger
+ * @return boolean
+ */
+ public boolean isBrowserAvailable(AbstractLogger logger);
+}
diff --git a/source/edu/stanford/ejalbert/launching/misc/UnixNetscapeBrowserLaunching.java b/source/edu/stanford/ejalbert/launching/misc/UnixNetscapeBrowserLaunching.java
new file mode 100644
index 0000000..5a899ef
--- /dev/null
+++ b/source/edu/stanford/ejalbert/launching/misc/UnixNetscapeBrowserLaunching.java
@@ -0,0 +1,375 @@
+/************************************************
+ Copyright 2004,2005,2006 Markus Gebhard, Jeff Chapman
+
+ This file is part of BrowserLauncher2.
+
+ BrowserLauncher2 is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ BrowserLauncher2 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with BrowserLauncher2; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ ************************************************/
+// $Id: UnixNetscapeBrowserLaunching.java,v 1.14 2006/11/07 14:08:31 jchapman0 Exp $
+package edu.stanford.ejalbert.launching.misc;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.TreeMap;
+
+import edu.stanford.ejalbert.exception.BrowserLaunchingExecutionException;
+import edu.stanford.ejalbert.exception.BrowserLaunchingInitializingException;
+import edu.stanford.ejalbert.exception.UnsupportedOperatingSystemException;
+import edu.stanford.ejalbert.launching.IBrowserLaunching;
+import net.sf.wraplog.AbstractLogger;
+
+/**
+ * Tries several browsers (mozilla, netscape, firefox, opera, and konqueror).
+ * Most users will have at least one of these installed. The types are
+ * defined in /edu/stanford/ejalbert/launching/misc/linuxUnixConfig.properties.
+ *
+ * @author Markus Gebhard, Jeff Chapman
+ */
+public class UnixNetscapeBrowserLaunching
+ implements IBrowserLaunching {
+ /**
+ * config file for linux/unix
+ */
+ public static final String CONFIGFILE_LINUX_UNIX =
+ "/edu/stanford/ejalbert/launching/misc/linuxUnixConfig.properties";
+ /**
+ * map of supported unix/linux browsers. The map contains
+ * displayName => StandardUnixBrowser mappings.
+ */
+ private Map unixBrowsers = new TreeMap(String.CASE_INSENSITIVE_ORDER);
+
+ protected final AbstractLogger logger; // in ctor
+ /**
+ * name of config file passed into constructor
+ */
+ private final String configFileName; // in ctor
+ /**
+ * new window policy to apply when opening a url. If true,
+ * try to force url into a new browser instance/window.
+ */
+ private boolean forceNewWindow = false;
+
+ /**
+ * Sets the logger and config file name.
+ *
+ * @param logger AbstractLogger
+ * @param configFile String
+ */
+ public UnixNetscapeBrowserLaunching(AbstractLogger logger,
+ String configFile) {
+ if (configFile == null) {
+ throw new IllegalArgumentException("config file cannot be null");
+ }
+ this.logger = logger;
+ this.configFileName = configFile;
+ }
+
+ /**
+ * Provides access the browsers map for extending classes.
+ *
+ * @param key String
+ * @return StandardUnixBrowser
+ */
+ protected StandardUnixBrowser getBrowser(String key) {
+ return (StandardUnixBrowser) unixBrowsers.get(key);
+ }
+
+ /**
+ * Attempts to open a url with the specified browser. This is
+ * a utility method called by the openUrl methods.
+ *
+ * @param unixBrowser UnixBrowser
+ * @param urlString String
+ * @return boolean
+ * @throws BrowserLaunchingExecutionException
+ */
+ protected boolean openUrlWithBrowser(UnixBrowser unixBrowser,
+ String urlString)
+ throws BrowserLaunchingExecutionException {
+ boolean success = false;
+ logger.info(unixBrowser.getBrowserDisplayName());
+ logger.info(urlString);
+ try {
+ int exitCode = -1;
+ Process process = null;
+ String[] args;
+ // try to open in a new tab/current instance
+ // skip this attempt if force new window is set to true
+ if (!forceNewWindow) {
+ args = unixBrowser.getArgsForOpenBrowser(urlString);
+ if (logger.isDebugEnabled()) {
+ logger.debug(Arrays.asList(args).toString());
+ }
+ process = Runtime.getRuntime().exec(args);
+ exitCode = process.waitFor();
+ }
+ // try call to force a new window if requested
+ if (forceNewWindow && exitCode != 0) {
+ args = unixBrowser.getArgsForForcingNewBrowserWindow(urlString);
+ if (logger.isDebugEnabled()) {
+ logger.debug(Arrays.asList(args).toString());
+ }
+ process = Runtime.getRuntime().exec(args);
+ exitCode = process.waitFor();
+ }
+ // open in a new window
+ if (exitCode != 0) {
+ args = unixBrowser.getArgsForStartingBrowser(urlString);
+ if (logger.isDebugEnabled()) {
+ logger.debug(Arrays.asList(args).toString());
+ }
+ process = Runtime.getRuntime().exec(args);
+ exitCode = process.waitFor();
+ }
+ if (exitCode == 0) {
+ success = true;
+ }
+ }
+ // Runtimes may throw InterruptedException
+ // want to catch every possible exception and wrap it
+ catch (Exception e) {
+ throw new BrowserLaunchingExecutionException(e);
+ }
+ return success;
+ }
+
+ /* ---------------------- from IBrowserLaunching ----------------------- */
+
+ /**
+ * Uses the which command to find out which browsers are available.
+ * The available browsers are put into the unixBrowsers map
+ * using displayName => StandardUnixBrowser mappings.
+ *
+ * @todo what do we do if there are no browsers available?
+ * @throws BrowserLaunchingInitializingException
+ */
+ public void initialize()
+ throws BrowserLaunchingInitializingException {
+ try {
+ URL configUrl = getClass().getResource(configFileName);
+ if (configUrl == null) {
+ throw new BrowserLaunchingInitializingException(
+ "unable to find config file: " + configFileName);
+ }
+ StringBuffer potentialBrowserNames = new StringBuffer();
+ Properties configProps = new Properties();
+ configProps.load(configUrl.openStream());
+ String sepChar = configProps.getProperty(PROP_KEY_DELIMITER);
+ Iterator keysIter = configProps.keySet().iterator();
+ while (keysIter.hasNext()) {
+ String key = (String) keysIter.next();
+ if (key.startsWith(PROP_KEY_BROWSER_PREFIX)) {
+ StandardUnixBrowser browser = new StandardUnixBrowser(
+ sepChar,
+ configProps.getProperty(key));
+ if (browser.isBrowserAvailable(logger)) {
+ unixBrowsers.put(browser.getBrowserDisplayName(),
+ browser);
+ }
+ else {
+ if (potentialBrowserNames.length() > 0) {
+ potentialBrowserNames.append("; ");
+ }
+ potentialBrowserNames.append(
+ browser.getBrowserDisplayName());
+ }
+ }
+ }
+ if (unixBrowsers.size() == 0) {
+ // no browser installed
+ throw new BrowserLaunchingInitializingException(
+ "one of the supported browsers must be installed: "
+ + potentialBrowserNames);
+ }
+ logger.info(unixBrowsers.keySet().toString());
+ unixBrowsers = Collections.unmodifiableMap(unixBrowsers);
+ }
+ catch (IOException ioex) {
+ throw new BrowserLaunchingInitializingException(ioex);
+ }
+ }
+
+ /**
+ * Opens a url in one of the available browsers.
+ *
+ * @param urlString String
+ * @throws BrowserLaunchingExecutionException
+ */
+ public void openUrl(String urlString)
+ throws UnsupportedOperatingSystemException,
+ BrowserLaunchingExecutionException,
+ BrowserLaunchingInitializingException {
+ try {
+ logger.info(urlString);
+ boolean success = false;
+ // get list of browsers to try
+ List unixBrowsersList = new ArrayList(unixBrowsers.values());
+ // check system property which may contain user's preferred browser
+ String browserId = System.getProperty(
+ IBrowserLaunching.BROWSER_SYSTEM_PROPERTY,
+ null);
+ if (browserId != null) {
+ UnixBrowser unixBrowser =
+ (UnixBrowser) unixBrowsers.get(browserId);
+ if (unixBrowser != null) {
+ // if user has preferred browser, place at start of list
+ unixBrowsersList.add(0, unixBrowser);
+ }
+ }
+ // iterate over browsers until one works
+ Iterator iter = unixBrowsersList.iterator();
+ UnixBrowser browser;
+ Process process;
+ while (iter.hasNext() && !success) {
+ browser = (UnixBrowser) iter.next();
+ success = openUrlWithBrowser(browser,
+ urlString);
+ }
+ }
+ catch (Exception e) {
+ throw new BrowserLaunchingExecutionException(e);
+ }
+ }
+
+ /**
+ * Opens a url in the specified browser. If the call to the
+ * specified browser fails, the method falls through to the
+ * non-targetted version.
+ *
+ * @param browser String
+ * @param urlString String
+ * @throws UnsupportedOperatingSystemException
+ * @throws BrowserLaunchingExecutionException
+ * @throws BrowserLaunchingInitializingException
+ */
+ public void openUrl(String browser,
+ String urlString)
+ throws UnsupportedOperatingSystemException,
+ BrowserLaunchingExecutionException,
+ BrowserLaunchingInitializingException {
+ UnixBrowser unixBrowser = (UnixBrowser) unixBrowsers.get(browser);
+ if (unixBrowser == null ||
+ IBrowserLaunching.BROWSER_DEFAULT.equals(browser)) {
+ logger.debug("falling through to non-targetted openUrl");
+ openUrl(urlString);
+ }
+ else {
+ boolean success = openUrlWithBrowser(unixBrowser,
+ urlString);
+ if (!success) {
+ logger.debug(
+ "open browser failure, trying non-targetted openUrl");
+ openUrl(urlString);
+ }
+ }
+ }
+
+ /**
+ * Allows user to target several browsers. The names of
+ * potential browsers can be accessed via the
+ * {@link #getBrowserList() getBrowserList} method.
+ * <p>
+ * The browsers from the list will be tried in order
+ * (first to last) until one of the calls succeeds. If
+ * all the calls to the requested browsers fail, the code
+ * will fail over to the default browser.
+ *
+ * @param browsers List
+ * @param urlString String
+ * @throws UnsupportedOperatingSystemException
+ * @throws BrowserLaunchingExecutionException
+ * @throws BrowserLaunchingInitializingException
+ */
+ public void openUrl(List browsers,
+ String urlString)
+ throws UnsupportedOperatingSystemException,
+ BrowserLaunchingExecutionException,
+ BrowserLaunchingInitializingException {
+ if (browsers == null || browsers.isEmpty()) {
+ logger.debug("falling through to non-targetted openUrl");
+ openUrl(urlString);
+ }
+ else {
+ boolean success = false;
+ Iterator iter = browsers.iterator();
+ while (iter.hasNext() && !success) {
+ UnixBrowser unixBrowser = (UnixBrowser) unixBrowsers.get(
+ iter.next());
+ if (unixBrowser != null) {
+ success = openUrlWithBrowser(unixBrowser,
+ urlString);
+ }
+ }
+ if (!success) {
+ logger.debug(
+ "none of listed browsers succeeded; falling through to non-targetted openUrl");
+ openUrl(urlString);
+ }
+ }
+ }
+
+ /**
+ * Returns a list of browsers to be used for browser
+ * targetting. This list will always contain at least
+ * one item--the BROWSER_DEFAULT.
+ *
+ * @return List
+ */
+ public List getBrowserList() {
+ List browsers = new ArrayList();
+ // add Default if not present
+ if (!unixBrowsers.containsKey(IBrowserLaunching.BROWSER_DEFAULT)) {
+ browsers.add(IBrowserLaunching.BROWSER_DEFAULT);
+ }
+ browsers.addAll(unixBrowsers.keySet());
+ return browsers;
+ }
+
+ /**
+ * Returns the policy used for opening a url in a browser.
+ * <p>
+ * If the policy is true, an attempt will be made to force the
+ * url to be opened in a new instance (window) of the
+ * browser.
+ * <p>
+ * If the policy is false, the url may open in a new window or
+ * a new tab.
+ * <p>
+ * Most browsers on Unix/Linux systems have command line options to
+ * support this feature.
+ *
+ * @return boolean
+ */
+ public boolean getNewWindowPolicy() {
+ return forceNewWindow;
+ }
+
+ /**
+ * Sets the policy used for opening a url in a browser.
+ *
+ * @param forceNewWindow boolean
+ */
+ public void setNewWindowPolicy(boolean forceNewWindow) {
+ this.forceNewWindow = forceNewWindow;
+ }
+}
diff --git a/source/edu/stanford/ejalbert/launching/misc/linuxUnixConfig.properties b/source/edu/stanford/ejalbert/launching/misc/linuxUnixConfig.properties
new file mode 100644
index 0000000..ff858fb
--- /dev/null
+++ b/source/edu/stanford/ejalbert/launching/misc/linuxUnixConfig.properties
@@ -0,0 +1,33 @@
+# ************************************************
+# Copyright 2006,2007 Jeff Chapman
+#
+# This file is part of BrowserLauncher2.
+#
+# BrowserLauncher2 is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# BrowserLauncher2 is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with BrowserLauncher2; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+# ************************************************
+# $Id: linuxUnixConfig.properties,v 1.3 2007/06/13 19:25:54 jchapman0 Exp $
+
+# delimiter for browser listing
+delimchar=;
+
+# list of browsers and arguments for using them
+# display name | executable name | start browser args | invoke already started browser | force new window
+browser.mozilla=Mozilla;mozilla;<browser> <url>;<browser> -remote openURL(<url>)
+browser.netscape=Netscape;netscape;<browser> <url>;<browser> -remote openURL(<url>)
+browser.firefox=FireFox;firefox;<browser> <url>;<browser> -new-tab <url>;<browser> -new-window <url>
+browser.mozilla-firefox=FireFox;mozilla-firefox;<browser> <url>;<browser> -remote openURL(<url>);<browser> -new-window <url>
+browser.konqueror=Konqueror;kfmclient;<browser> openURL <url>;<browser> newTab <url>;<browser> openURL <url>
+browser.opera=Opera;opera;<browser> <url>;<browser> -newpage <url>;<browser> -newwindow <url>
+browser.epiphany=Epiphany;epiphany;<browser> <url>;<browser> --new-tab <url>
diff --git a/source/edu/stanford/ejalbert/launching/misc/sunOSConfig.properties b/source/edu/stanford/ejalbert/launching/misc/sunOSConfig.properties
new file mode 100644
index 0000000..af32b42
--- /dev/null
+++ b/source/edu/stanford/ejalbert/launching/misc/sunOSConfig.properties
@@ -0,0 +1,32 @@
+# ************************************************
+# Copyright 2006 Jeff Chapman
+#
+# This file is part of BrowserLauncher2.
+#
+# BrowserLauncher2 is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# BrowserLauncher2 is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with BrowserLauncher2; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+# ************************************************
+# $Id: sunOSConfig.properties,v 1.2 2006/09/12 15:40:34 jchapman0 Exp $
+
+# delimiter for browser listing
+delimchar=;
+
+# list of browsers and arguments for using them
+# display name | executable name | start browser args | invoke already started browser
+browser.sdtwebclient=Default;sdtwebclient;<browser> <url>;<browser> -remote openURL(<url>)
+browser.mozilla=Mozilla;mozilla;<browser> <url>;<browser> -remote openURL(<url>)
+browser.netscape=Netscape;netscape;<browser> <url>;<browser> -remote openURL(<url>)
+browser.firefox=FireFox;firefox;<browser> <url>;<browser> -remote openURL(<url>);<browser> -new-window <url>
+browser.opera=Opera;opera;<browser> <url>;<browser> -newpage <url>;<browser> -newwindow <url>
+
diff --git a/source/edu/stanford/ejalbert/launching/utils/LaunchingUtils.java b/source/edu/stanford/ejalbert/launching/utils/LaunchingUtils.java
new file mode 100644
index 0000000..a0d1088
--- /dev/null
+++ b/source/edu/stanford/ejalbert/launching/utils/LaunchingUtils.java
@@ -0,0 +1,55 @@
+/************************************************
+ Copyright 2007 Jeff Chapman
+
+ This file is part of BrowserLauncher2.
+
+ BrowserLauncher2 is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ BrowserLauncher2 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with BrowserLauncher2; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ ************************************************/
+// $Id: LaunchingUtils.java,v 1.1 2007/08/31 16:05:56 jchapman0 Exp $
+package edu.stanford.ejalbert.launching.utils;
+
+/**
+ *
+ * @author not attributable
+ * @version 1.0
+ */
+public class LaunchingUtils {
+ private static final String REPLACE_BROWSER = "<browser>";
+ private static final String REPLACE_URL = "<url>";
+
+ public static String replaceArgs(String commands,
+ String browserArg,
+ String urlArg) {
+ // replace <browser> placeholder if browserArg passed
+ if(browserArg != null) {
+ commands = commands.replaceAll(REPLACE_BROWSER, browserArg);
+ }
+ // replace <url> placeholder if urlArg passed
+ if(urlArg != null) {
+ int urlPos = commands.indexOf(REPLACE_URL);
+ StringBuffer buf = new StringBuffer();
+ while (urlPos > 0) {
+ buf.append(commands.substring(0, urlPos));
+ buf.append(urlArg);
+ buf.append(commands.substring(urlPos + REPLACE_URL.length()));
+ commands = buf.toString();
+ urlPos = commands.indexOf(REPLACE_URL);
+ buf.setLength(0);
+ }
+ }
+ return commands;
+ }
+}
diff --git a/source/edu/stanford/ejalbert/launching/windows/WindowsBrowser.java b/source/edu/stanford/ejalbert/launching/windows/WindowsBrowser.java
new file mode 100644
index 0000000..be20bfe
--- /dev/null
+++ b/source/edu/stanford/ejalbert/launching/windows/WindowsBrowser.java
@@ -0,0 +1,147 @@
+/************************************************
+ Copyright 2005,2006,2007 Jeff Chapman
+
+ This file is part of BrowserLauncher2.
+
+ BrowserLauncher2 is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ BrowserLauncher2 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with BrowserLauncher2; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ ************************************************/
+// $Id: WindowsBrowser.java,v 1.6 2007/01/31 18:27:26 jchapman0 Exp $
+package edu.stanford.ejalbert.launching.windows;
+
+import edu.stanford.ejalbert.launching.BrowserDescription;
+
+/**
+ * Encapsulates information on a Windows browser.
+ *
+ * @author Jeff Chapman
+ * @version 1.0
+ */
+public class WindowsBrowser
+ implements BrowserDescription {
+ /**
+ * The name for the browser suitable for display to a user.
+ */
+ private final String displayName; // in ctor
+ /**
+ * The name of the executable for the browser.
+ */
+ private final String exe; // in ctor
+ /**
+ * Arguments used in call to browser that will force the url to open in a new window rather than a new tab.
+ */
+ private final String forceWindowArgs; // in ctor
+ /**
+ * The path to the browsers executable. This is used to
+ * invoke the browser directly when using browser targetting.
+ */
+ private String pathToExe = null;
+ /**
+ * Name of the sub directory under Program Files in which
+ * the browser exe is typically installed.
+ * <p>
+ * This value is used as a secondary means of discovery if
+ * attempts with the Registry fail.
+ */
+ private final String subDirName;// in ctor
+
+ /**
+ * Splits the config string using the delimiter character and
+ * sets the display name; executable; new window argument; and
+ * Program Files sub directory name.
+ * <p>
+ * Sample config string (with ; as the delim char): displayName;exeName
+ *
+ * @param delimChar String
+ * @param configInfo String
+ */
+ WindowsBrowser(String delimChar,
+ String configInfo) {
+ // we should always have four items in the config string
+ String[] configItems = configInfo.split(delimChar,4);
+ this.displayName = configItems[0];
+ this.exe = configItems[1];
+ this.forceWindowArgs = configItems[2];
+ this.subDirName = configItems[3];
+ }
+
+ /**
+ * Returns displayname and executable name for debugging.
+ *
+ * @return String
+ */
+ public String toString() {
+ StringBuffer buf = new StringBuffer();
+ buf.append(displayName);
+ buf.append(": ForceWindowArg=");
+ buf.append(forceWindowArgs);
+ buf.append("; SubDir name=");
+ buf.append(subDirName);
+ buf.append("; Path to exe=");
+ if(pathToExe != null) {
+ buf.append(pathToExe);
+ }
+ buf.append("; Exe name=");
+ buf.append(exe);
+ return buf.toString();
+ }
+
+ void setPathToExe(String path) {
+ pathToExe = path;
+ if(!pathToExe.endsWith("\\")) {
+ StringBuffer buf = new StringBuffer(pathToExe.length() + 2);
+ buf.append(pathToExe);
+ buf.append('\\');
+ pathToExe = buf.toString();
+ }
+ }
+
+ String getPathToExe() {
+ return pathToExe;
+ }
+
+ String getSubDirName() {
+ return subDirName;
+ }
+
+ /* -------------------- from BrowserDescription ---------------------- */
+
+ /**
+ * Returns the display name for the browser.
+ *
+ * @return String
+ */
+ public String getBrowserDisplayName() {
+ return displayName;
+ }
+
+ /**
+ * Returns the name of the executable for the browser.
+ *
+ * @return String
+ */
+ public String getBrowserApplicationName() {
+ return exe;
+ }
+
+ /**
+ * Returns arguments used for forcing a new window. May be an empty String.
+ *
+ * @return String
+ */
+ public String getForceNewWindowArgs() {
+ return forceWindowArgs;
+ }
+}
diff --git a/source/edu/stanford/ejalbert/launching/windows/WindowsBrowserLaunching.java b/source/edu/stanford/ejalbert/launching/windows/WindowsBrowserLaunching.java
new file mode 100644
index 0000000..41de3af
--- /dev/null
+++ b/source/edu/stanford/ejalbert/launching/windows/WindowsBrowserLaunching.java
@@ -0,0 +1,857 @@
+/************************************************
+ Copyright 2004,2005,2006,2007 Markus Gebhard, Jeff Chapman
+
+ This file is part of BrowserLauncher2.
+
+ BrowserLauncher2 is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ BrowserLauncher2 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with BrowserLauncher2; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ ************************************************/
+// $Id: WindowsBrowserLaunching.java,v 1.13 2007/08/31 15:54:10 jchapman0 Exp $
+package edu.stanford.ejalbert.launching.windows;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.StringTokenizer;
+import java.util.TreeMap;
+
+import at.jta.RegistryErrorException;
+import at.jta.Regor;
+import edu.stanford.ejalbert.exception.BrowserLaunchingExecutionException;
+import edu.stanford.ejalbert.exception.BrowserLaunchingInitializingException;
+import edu.stanford.ejalbert.exception.UnsupportedOperatingSystemException;
+import edu.stanford.ejalbert.launching.IBrowserLaunching;
+import net.sf.wraplog.AbstractLogger;
+import edu.stanford.ejalbert.launching.utils.LaunchingUtils;
+
+/**
+ * Handles initialization, configuration, and calls to open a url.
+ *
+ * @author Markus Gebhard, Jeff Chapman, Chris Dance
+ */
+public class WindowsBrowserLaunching
+ implements IBrowserLaunching {
+ /**
+ * windows configuration file -- info on commands and browsers
+ */
+ private static final String CONFIGFILE_WINDOWS =
+ "/edu/stanford/ejalbert/launching/windows/windowsConfig.properties";
+ /**
+ * config file key for Windows Vista
+ */
+ public static final String WINKEY_WINVISTA = "windows.winVista";
+ /**
+ * config file key for Windows 2000
+ */
+ public static final String WINKEY_WIN2000 = "windows.win2000";
+ /**
+ * config file key for Windows 9x
+ */
+ public static final String WINKEY_WIN9X = "windows.win9x";
+ /**
+ * config file key for Windows NT
+ */
+ public static final String WINKEY_WINNT = "windows.winNT";
+ /**
+ * collects valid config keys for key validation
+ */
+ private static final String[] WIN_KEYS = {
+ WINKEY_WIN2000,
+ WINKEY_WIN9X,
+ WINKEY_WINNT,
+ WINKEY_WINVISTA};
+ static {
+ Arrays.sort(WIN_KEYS);
+ }
+
+ protected final AbstractLogger logger; // in ctor
+
+ /**
+ * Maps display name and exe name to {@link WindowsBrowser WindowsBrowser}
+ * objects. Using name and exe as keys for backward compatiblity.
+ */
+ private Map browserNameAndExeMap = null;
+
+ /**
+ * List of {@link WindowsBrowser WindowsBrowser} objects that
+ * will be used to determine which browsers are available
+ * on the machine. The list is created from the windows
+ * config file.
+ */
+ private List browsersToCheck = new ArrayList();
+
+ /**
+ * Arguments for starting the default browser.
+ */
+ private String commandsDefaultBrowser; // in initialize
+ /**
+ * Arguments for starting a specific browser.
+ */
+ private String commandsTargettedBrowser; // in initialize
+ /**
+ * The key for accessing information from the windows config
+ * file for a particular version of windows.
+ * @see WINKEY_WIN2000
+ * @see WINKEY_WIN9X
+ * @see WINKEY_WINNT
+ */
+ private final String windowsKey; // in ctor
+ /**
+ * new window policy to apply when opening a url. If true,
+ * try to force url into a new browser instance/window.
+ */
+ private boolean forceNewWindow = false;
+
+ /**
+ * set from properties to determine if the registry
+ * should be consulted for available browsers.
+ * Vista does not allow universal access to the registry.
+ */
+ private boolean useRegistry = false;
+
+ private String programFilesFolderTemplate;
+ private String driveLetters;
+
+ // constants defined for accessing and processing registry information
+ //private static final int REGEDIT_TYPE_APPPATHS = 0;
+ //private static final int REGEDIT_TYPE_UNINSTALL = 1;
+ //private static String[] regeditQueries = {
+ // "\"HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\""};
+ //"\"HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\""};
+
+ /**
+ * Checks that the windows key is valid.
+ *
+ * @param logger AbstractLogger
+ * @param windowsKey String
+ */
+ public WindowsBrowserLaunching(AbstractLogger logger,
+ String windowsKey) {
+ if (windowsKey == null) {
+ throw new IllegalArgumentException("windowsKey cannot be null");
+ }
+ if (Arrays.binarySearch(WIN_KEYS, windowsKey) < 0) {
+ throw new IllegalArgumentException(windowsKey + " is invalid");
+ }
+ this.logger = logger;
+ this.windowsKey = windowsKey;
+ logger.info(windowsKey);
+ }
+
+ private String getArrayAsString(String[] array) {
+ return Arrays.asList(array).toString();
+ }
+
+ /**
+ * Returns the protocol for the url.
+ *
+ * @param urlString String
+ * @return String
+ * @throws MalformedURLException
+ */
+ private String getProtocol(String urlString)
+ throws MalformedURLException {
+ URL url = new URL(urlString);
+ return url.getProtocol();
+ }
+
+ /**
+ * Returns map of browser names and exe names to
+ * {@link WindowsBrowser WindowsBrowser} objects.
+ * <p>
+ * This is the preferred method for accessing the browser name and exe map.
+ * @return Map
+ */
+ private Map getBrowserMap() {
+ // Handles lazy instantiation of available browser map.
+ synchronized (WindowsBrowserLaunching.class) {
+ if (browserNameAndExeMap == null) {
+ browserNameAndExeMap = new HashMap();
+ // pull additional browsers from system property??
+ // ---------
+ // create temporary list of browsers to check to track which
+ // ones have been found
+ // we will remove items from this temp list
+ List tempBrowsersToCheck = new ArrayList(browsersToCheck);
+ // first try the registry
+ if (useRegistry) {
+ browserNameAndExeMap.putAll(
+ getAvailableBrowsers(tempBrowsersToCheck));
+ }
+ // if there are still browsers to find, try file path
+ if (!tempBrowsersToCheck.isEmpty()) {
+ browserNameAndExeMap.putAll(
+ processFilePathsForBrowsers(tempBrowsersToCheck));
+ }
+ }
+ }
+ return browserNameAndExeMap;
+ }
+
+ /**
+ * Use program files folder template from properties file and
+ * the list of drive letters from that properties file
+ * @return File
+ */
+ private File getProgramFilesPath() {
+ File progFilesPath = null;
+ if (driveLetters != null && programFilesFolderTemplate != null) {
+ String[] drives = driveLetters.split(";");
+ for (int idx = 0; idx < drives.length && progFilesPath == null; idx++) {
+ String path = MessageFormat.format(
+ programFilesFolderTemplate,
+ new Object[] {drives[idx]});
+ File pfPath = new File(path);
+ logger.debug(path);
+ logger.debug(pfPath.getPath());
+ if (pfPath.exists()) {
+ progFilesPath = pfPath;
+ }
+ }
+ }
+ return progFilesPath;
+ }
+
+ /**
+ * Secondary method for browser discovery.
+ * <p>
+ * Uses IE to get the path to the Program Files directory;
+ * then gets a list of the sub dirs and checks them against
+ * the remaining browsers.
+ *
+ * @param iePath String
+ * @param browsersAvailable Map
+ * @param tmpBrowsersToCheck List
+ */
+ private Map processFilePathsForBrowsers(
+ List tmpBrowsersToCheck) {
+ logger.debug("finding available browsers in program files path");
+ logger.debug("browsers to check: " + tmpBrowsersToCheck);
+ Map browsersAvailable = new HashMap();
+ File progFilesPath = getProgramFilesPath();
+ if (progFilesPath != null) {
+ logger.debug("program files path: " + progFilesPath.getPath());
+ File[] subDirs = progFilesPath.listFiles(new DirFileFilter());
+ int subDirsCnt = subDirs != null ? subDirs.length : 0;
+ // create and populate map of dir names to win browser objects
+ Iterator iter = tmpBrowsersToCheck.iterator();
+ Map dirNameToBrowser = new HashMap();
+ while (iter.hasNext()) {
+ WindowsBrowser wBrowser = (WindowsBrowser) iter.next();
+ dirNameToBrowser.put(wBrowser.getSubDirName(), wBrowser);
+ }
+ // iterate over subdirs and compare to map entries
+ for (int idx = 0; idx < subDirsCnt && !tmpBrowsersToCheck.isEmpty();
+ idx++) {
+ if (dirNameToBrowser.containsKey(subDirs[idx].getName())) {
+ WindowsBrowser wBrowser = (WindowsBrowser) dirNameToBrowser.
+ get(
+ subDirs[idx].getName());
+ // need to search folder and sub-folders for exe to find
+ // the full path
+ String exeName = wBrowser.getBrowserApplicationName() +
+ ".exe";
+ File fullPathToExe = findExeFilePath(
+ subDirs[idx],
+ exeName);
+ if (fullPathToExe != null) {
+ logger.debug("Adding browser " +
+ wBrowser.getBrowserDisplayName() +
+ " to available list.");
+ wBrowser.setPathToExe(fullPathToExe.getPath());
+ logger.debug(wBrowser.getPathToExe());
+ // adding display and exe for backward compatibility and
+ // ease of use if someone passes in the name of an exe
+ browsersAvailable.put(wBrowser.getBrowserDisplayName(),
+ wBrowser);
+ browsersAvailable.put(wBrowser.
+ getBrowserApplicationName(),
+ wBrowser);
+ tmpBrowsersToCheck.remove(wBrowser);
+ }
+ }
+ }
+ }
+ return browsersAvailable;
+ }
+
+ private File findExeFilePath(File path, String exeName) {
+ File exePath = null;
+ File exeFiles[] = path.listFiles(new ExeFileNameFilter());
+ if (exeFiles != null && exeFiles.length > 0) {
+ for (int idx = 0; idx < exeFiles.length && exePath == null; idx++) {
+ if (exeFiles[idx].getName().equalsIgnoreCase(exeName)) {
+ // found the exe, get parent
+ exePath = exeFiles[idx].getParentFile();
+ }
+ }
+ }
+ // didn't find the exe
+ if (exePath == null) {
+ File[] subDirs = path.listFiles(new DirFileFilter());
+ if (subDirs != null && subDirs.length > 0) {
+ for (int idx = 0; idx < subDirs.length && exePath == null; idx++) {
+ exePath = findExeFilePath(subDirs[idx], exeName);
+ }
+ }
+ }
+ return exePath;
+ }
+
+ /**
+ * Filter used to only select directories.
+ */
+ private static final class DirFileFilter
+ implements FileFilter {
+ public boolean accept(File pathname) {
+ return pathname.isDirectory();
+ }
+ }
+
+
+ /**
+ * Filter used to only find exe files.
+ */
+ private static final class ExeFileNameFilter
+ implements FilenameFilter {
+ public boolean accept(File dir, String name) {
+ return name.toLowerCase().endsWith(".exe");
+ }
+ }
+
+
+ private Map getExeNamesToBrowsers(List tempBrowsersToCheck) {
+ Map exeNamesToBrowsers = new HashMap();
+ Iterator iter = tempBrowsersToCheck.iterator();
+ while (iter.hasNext()) {
+ WindowsBrowser winBrowser = (WindowsBrowser) iter.next();
+ String exeName = winBrowser.getBrowserApplicationName().
+ toLowerCase() + ".exe";
+ exeNamesToBrowsers.put(exeName, winBrowser);
+ }
+ return exeNamesToBrowsers;
+ }
+
+ private WindowsBrowser getBrowserFromRegistryEntry(
+ Regor regor,
+ int key,
+ String subKey,
+ String exeKey,
+ Map exesToBrowserObjs)
+ throws RegistryErrorException {
+ WindowsBrowser winBrowser = null;
+ int key2 = regor.openKey(key, subKey);
+ List values = regor.listValueNames(key2);
+ //boolean fndPath = false;
+ for (int x = 0;
+ values != null && x < values.size() && winBrowser == null;
+ x++) {
+ byte[] buf = regor.readValue(
+ key2,
+ (String) values.get(x));
+ String path = buf != null ? Regor.parseValue(buf) :
+ "";
+ String lpath = path.toLowerCase();
+ if (lpath.endsWith(exeKey)) {
+ winBrowser = (WindowsBrowser)
+ exesToBrowserObjs.get(exeKey);
+ // get path to exe and set it in winBrowser object
+ StringTokenizer tokenizer =
+ new StringTokenizer(path, "\\", false);
+ StringBuffer pathBuf = new StringBuffer();
+ int tokCnt = tokenizer.countTokens();
+ // we want to ignore the last token
+ for (int idx = 1; idx < tokCnt; idx++) {
+ pathBuf.append(tokenizer.nextToken());
+ pathBuf.append('\\');
+ }
+ winBrowser.setPathToExe(pathBuf.toString());
+ }
+ }
+ return winBrowser;
+ }
+
+ /**
+ * Accesses the Windows registry to look for browser exes. The
+ * browsers search for are in the browsersToCheck list. The returned
+ * map will use display names and exe names as keys to the
+ * {@link WindowsBrowser WindowsBrowser} objects.
+ *
+ * @param browsersToCheck List
+ * @return Map
+ */
+ private Map getAvailableBrowsers(List tempBrowsersToCheck) {
+ logger.debug("finding available browsers using registry");
+ logger.debug("browsers to check: " + tempBrowsersToCheck);
+ Map browsersAvailable = new TreeMap(String.CASE_INSENSITIVE_ORDER);
+ try {
+ // create map of exe names to win browser objects
+ Map exesToBrowserObjs = getExeNamesToBrowsers(tempBrowsersToCheck);
+ // access and look in registry
+ Regor regor = new Regor();
+ String subKeyName =
+ "Software\\Microsoft\\Windows\\CurrentVersion\\App Paths";
+ int key = regor.openKey(Regor.HKEY_LOCAL_MACHINE,
+ subKeyName);
+ if (key > -1) {
+ List keys = regor.listKeys(key);
+ Collections.sort(keys, String.CASE_INSENSITIVE_ORDER);
+ Iterator keysIter = exesToBrowserObjs.keySet().iterator();
+ while (keysIter.hasNext()) {
+ String exeKey = (String) keysIter.next();
+ int index = Collections.binarySearch(
+ keys,
+ exeKey,
+ String.CASE_INSENSITIVE_ORDER);
+ if (index >= 0) {
+ WindowsBrowser winBrowser = getBrowserFromRegistryEntry(
+ regor,
+ key,
+ (String) keys.get(index),
+ exeKey,
+ exesToBrowserObjs);
+ if (winBrowser != null) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Adding browser " +
+ winBrowser.
+ getBrowserDisplayName() +
+ " to available list.");
+ logger.debug(winBrowser.getPathToExe());
+ }
+ // adding display and exe for backward compatibility and
+ // ease of use if someone passes in the name of an exe
+ browsersAvailable.put(winBrowser.
+ getBrowserDisplayName(),
+ winBrowser);
+ browsersAvailable.put(winBrowser.
+ getBrowserApplicationName(),
+ winBrowser);
+ tempBrowsersToCheck.remove(winBrowser);
+ }
+ }
+ }
+ }
+ }
+ catch (RegistryErrorException ex) {
+ logger.error("problem accessing registry", ex);
+ }
+ return browsersAvailable;
+ }
+
+ /**
+ * Returns the windows arguments for launching a default browser.
+ *
+ * @param protocol String
+ * @param urlString String
+ * @return String[]
+ */
+ private String[] getCommandArgs(String protocol,
+ String urlString) {
+ String commandArgs = LaunchingUtils.replaceArgs(
+ commandsDefaultBrowser,
+ null,
+ urlString);
+ return commandArgs.split("[ ]");
+ }
+
+ /**
+ * Returns the windows arguments for launching a specified browser.
+ * <p>
+ * Depending on the forceNewWindow boolean, the args may also contain the
+ * args to force a new window.
+ *
+ * @param protocol String
+ * @param winbrowser WindowsBrowser
+ * @param urlString String
+ * @param forceNewWindow boolean
+ * @return String[]
+ */
+ private String getCommandArgs(String protocol,
+ WindowsBrowser winbrowser,
+ String urlString,
+ boolean forceNewWindow) {
+ String commandArgs = LaunchingUtils.replaceArgs(
+ commandsTargettedBrowser,
+ winbrowser.getBrowserApplicationName(),
+ urlString);
+ String args = "";
+ if (forceNewWindow) {
+ args = winbrowser.getForceNewWindowArgs();
+ }
+ commandArgs = commandArgs.replaceAll("<args>", args);
+ int pathLoc = commandArgs.indexOf("<path>");
+ if (pathLoc > 0) {
+ StringBuffer buf = new StringBuffer();
+ buf.append(commandArgs.substring(0, pathLoc));
+ buf.append(winbrowser.getPathToExe());
+ buf.append(commandArgs.substring(pathLoc + 6));
+ commandArgs = buf.toString();
+ }
+ return commandArgs; //.split("[ ]");
+ }
+
+ /**
+ * Attempts to open a url with the specified browser. This is
+ * a utility method called by the openUrl methods.
+ *
+ * @param winBrowser WindowsBrowser
+ * @param protocol String
+ * @param urlString String
+ * @return boolean
+ * @throws BrowserLaunchingExecutionException
+ */
+ private boolean openUrlWithBrowser(WindowsBrowser winBrowser,
+ String protocol,
+ String urlString)
+ throws BrowserLaunchingExecutionException {
+ boolean success = false;
+ try {
+ logger.info(winBrowser.getBrowserDisplayName());
+ logger.info(urlString);
+ logger.info(protocol);
+ String args = getCommandArgs(
+ protocol,
+ winBrowser,
+ urlString,
+ forceNewWindow);
+ if (logger.isDebugEnabled()) {
+ logger.debug(args);
+ }
+ Process process = Runtime.getRuntime().exec(args);
+ // This avoids a memory leak on some versions of Java on Windows.
+ // That's hinted at in <http://developer.java.sun.com/developer/qow/archive/68/>.
+ process.waitFor();
+ // some browsers (mozilla, firefox) return 1 if you attempt to
+ // open a url and an instance of that browser is already running
+ // not clear why because the call is succeeding, ie the browser
+ // opens the url.
+ // If we don't say 1 is also a success, we get two browser
+ // windows or tabs opened to the url.
+ //
+ // We could make this check smarter in the future if we run
+ // into problems. the winBrowser object could handle the
+ // check to make it browser specific.
+ int exitValue = process.exitValue();
+ success = exitValue == 0 || exitValue == 1;
+ }
+ // Runtimes may throw InterruptedException
+ // want to catch every possible exception and wrap it
+ catch (Exception e) {
+ throw new BrowserLaunchingExecutionException(e);
+ }
+ return success;
+ }
+
+ /* ----------------- from IBrowserLaunching -------------------- */
+
+ /**
+ * Initializes the browser launcher from the windows config
+ * file. It initializes the browsers to check list and
+ * the command line args to use for version of windows
+ * referenced by the windowsKey.
+ *
+ * @see windowsKey
+ * @throws BrowserLaunchingInitializingException
+ */
+ public void initialize()
+ throws BrowserLaunchingInitializingException {
+ try {
+ URL configUrl = getClass().getResource(CONFIGFILE_WINDOWS);
+ if (configUrl == null) {
+ throw new BrowserLaunchingInitializingException(
+ "unable to find config file: " + CONFIGFILE_WINDOWS);
+ }
+ Properties configProps = new Properties();
+ configProps.load(configUrl.openStream());
+ // get sep char
+ String sepChar = configProps.getProperty(PROP_KEY_DELIMITER);
+ // load different types of browsers
+ Iterator keysIter = configProps.keySet().iterator();
+ while (keysIter.hasNext()) {
+ String key = (String) keysIter.next();
+ if (key.startsWith(PROP_KEY_BROWSER_PREFIX)) {
+ WindowsBrowser winBrowser = new WindowsBrowser(
+ sepChar,
+ configProps.getProperty(key));
+ browsersToCheck.add(winBrowser);
+ }
+ }
+ // load the type of windows based on the windows key
+ String windowsConfigStr = configProps.getProperty(
+ windowsKey,
+ null);
+ if (windowsConfigStr == null) {
+ throw new BrowserLaunchingInitializingException(
+ windowsKey + " is not a valid property");
+ }
+ String[] winConfigItems = windowsConfigStr.split(sepChar);
+ commandsDefaultBrowser = winConfigItems[0];
+ commandsTargettedBrowser = winConfigItems[1];
+ Boolean boolVal = new Boolean(winConfigItems[2]);
+ useRegistry = boolVal.booleanValue();
+ // check for override of useRegistry from system prop
+ // need to explicitly check BOTH values to filter out
+ // invalid prop values
+ String propValue = System.getProperty(
+ IBrowserLaunching.WINDOWS_BROWSER_DISC_POLICY_PROPERTY,
+ null);
+ if (IBrowserLaunching.WINDOWS_BROWSER_DISC_POLICY_DISK.equals(
+ propValue)) {
+ useRegistry = false;
+ }
+ else if (IBrowserLaunching.WINDOWS_BROWSER_DISC_POLICY_REGISTRY.
+ equals(propValue)) {
+ useRegistry = true;
+ }
+ if (logger.isDebugEnabled()) {
+ logger.debug("Browser discovery policy property value=" +
+ (propValue == null ? "null" : propValue));
+ logger.debug("useRegistry=" + Boolean.toString(useRegistry));
+ }
+ // get info for checking Program Files folder
+ programFilesFolderTemplate = configProps.getProperty(
+ "program.files.template",
+ null);
+ driveLetters = configProps.getProperty(
+ "drive.letters",
+ null);
+ // set brwosersToCheck to a non-modifiable list
+ browsersToCheck = Collections.unmodifiableList(browsersToCheck);
+ }
+ catch (IOException ioex) {
+ throw new BrowserLaunchingInitializingException(ioex);
+ }
+ }
+
+ /**
+ * Opens a url using the default browser.
+ *
+ * @param urlString String
+ * @throws UnsupportedOperatingSystemException
+ * @throws BrowserLaunchingExecutionException
+ * @throws BrowserLaunchingInitializingException
+ */
+ public void openUrl(String urlString)
+ throws UnsupportedOperatingSystemException,
+ BrowserLaunchingExecutionException,
+ BrowserLaunchingInitializingException {
+ try {
+ logger.info(urlString);
+ String protocol = getProtocol(urlString);
+ logger.info(protocol);
+ // try the system prop first
+ boolean successfullSystemPropLaunch = false;
+ String browserName = System.getProperty(
+ IBrowserLaunching.BROWSER_SYSTEM_PROPERTY,
+ null);
+ if (browserName != null) {
+ Map browserMap = getBrowserMap();
+ WindowsBrowser winBrowser = (WindowsBrowser) browserMap.get(
+ browserName);
+ if (winBrowser != null) {
+ logger.debug("using browser from system property");
+ successfullSystemPropLaunch = openUrlWithBrowser(
+ winBrowser,
+ protocol,
+ urlString);
+ }
+ }
+ if (!successfullSystemPropLaunch) {
+ String[] args = getCommandArgs(protocol,
+ urlString);
+ if (logger.isDebugEnabled()) {
+ logger.debug(getArrayAsString(args));
+ }
+ Process process = Runtime.getRuntime().exec(args);
+ // This avoids a memory leak on some versions of Java on Windows.
+ // That's hinted at in <http://developer.java.sun.com/developer/qow/archive/68/>.
+ process.waitFor();
+ process.exitValue();
+ }
+ }
+ catch (Exception e) {
+ logger.error("fatal exception", e);
+ throw new BrowserLaunchingExecutionException(e);
+ }
+ }
+
+ /**
+ * Opens a url using a specific browser.
+ * <p>
+ * If the specified browser is not available, the method will
+ * fall through to calling the default openUrl method.
+ *
+ * @param browser String
+ * @param urlString String
+ * @throws UnsupportedOperatingSystemException
+ * @throws BrowserLaunchingExecutionException
+ * @throws BrowserLaunchingInitializingException
+ */
+ public void openUrl(String browser,
+ String urlString)
+ throws UnsupportedOperatingSystemException,
+ BrowserLaunchingExecutionException,
+ BrowserLaunchingInitializingException {
+ if (IBrowserLaunching.BROWSER_DEFAULT.equals(browser) ||
+ browser == null) {
+ logger.info(
+ "default or null browser target; falling through to non-targetted openUrl");
+ openUrl(urlString);
+ }
+ else {
+ Map browserMap = getBrowserMap();
+ WindowsBrowser winBrowser = (WindowsBrowser) browserMap.get(browser);
+ if (winBrowser == null) {
+ logger.info("the available browsers list does not contain: " +
+ browser);
+ logger.info("falling through to non-targetted openUrl");
+ openUrl(urlString);
+ }
+ else {
+ String protocol = null;
+ try {
+ protocol = getProtocol(urlString);
+ }
+ catch (MalformedURLException malrulex) {
+ throw new BrowserLaunchingExecutionException(malrulex);
+ }
+ boolean successfullLaunch = openUrlWithBrowser(
+ winBrowser,
+ protocol,
+ urlString);
+ if (!successfullLaunch) {
+ logger.debug("falling through to non-targetted openUrl");
+ openUrl(urlString);
+ }
+ }
+ }
+ }
+
+ /**
+ * Allows user to target several browsers. The names of
+ * potential browsers can be accessed via the
+ * {@link #getBrowserList() getBrowserList} method.
+ * <p>
+ * The browsers from the list will be tried in order
+ * (first to last) until one of the calls succeeds. If
+ * all the calls to the requested browsers fail, the code
+ * will fail over to the default browser.
+ *
+ * @param browsers List
+ * @param urlString String
+ * @throws UnsupportedOperatingSystemException
+ * @throws BrowserLaunchingExecutionException
+ * @throws BrowserLaunchingInitializingException
+ */
+ public void openUrl(List browsers,
+ String urlString)
+ throws UnsupportedOperatingSystemException,
+ BrowserLaunchingExecutionException,
+ BrowserLaunchingInitializingException {
+ if (browsers == null || browsers.isEmpty()) {
+ logger.debug("falling through to non-targetted openUrl");
+ openUrl(urlString);
+ }
+ else {
+ String protocol = null;
+ try {
+ protocol = getProtocol(urlString);
+ }
+ catch (MalformedURLException malrulex) {
+ throw new BrowserLaunchingExecutionException(malrulex);
+ }
+ Map browserMap = getBrowserMap();
+ boolean success = false;
+ Iterator iter = browsers.iterator();
+ while (iter.hasNext() && !success) {
+ WindowsBrowser winBrowser = (WindowsBrowser) browserMap.get(
+ iter.next());
+ if (winBrowser != null) {
+ success = openUrlWithBrowser(winBrowser,
+ protocol,
+ urlString);
+ }
+ }
+ if (!success) {
+ logger.debug(
+ "none of listed browsers succeeded; falling through to non-targetted openUrl");
+ openUrl(urlString);
+ }
+ }
+ }
+
+
+ /**
+ * Returns a list of browsers to be used for browser targetting.
+ * This list will always contain at least one item--the BROWSER_DEFAULT.
+ *
+ * @return List
+ */
+ public List getBrowserList() {
+ Map browserMap = getBrowserMap();
+ List browsers = new ArrayList();
+ browsers.add(IBrowserLaunching.BROWSER_DEFAULT);
+ // exes are present in the map as well as display names
+ Iterator iter = browserMap.keySet().iterator();
+ while (iter.hasNext()) {
+ String key = (String) iter.next();
+ WindowsBrowser winBrowser = (WindowsBrowser) browserMap.get(key);
+ if (key.equals(winBrowser.getBrowserDisplayName())) {
+ browsers.add(winBrowser.getBrowserDisplayName());
+ }
+ }
+ return browsers;
+ }
+
+ /**
+ * Returns the policy used for opening a url in a browser.
+ * <p>
+ * If the policy is true, an attempt will be made to force the
+ * url to be opened in a new instance (window) of the
+ * browser.
+ * <p>
+ * If the policy is false, the url may open in a new window or
+ * a new tab.
+ * <p>
+ * Some browsers on Windows systems have command line options to
+ * support this feature.
+ *
+ * @return boolean
+ */
+ public boolean getNewWindowPolicy() {
+ return forceNewWindow;
+ }
+
+ /**
+ * Sets the policy used for opening a url in a browser.
+ *
+ * @param forceNewWindow boolean
+ */
+ public void setNewWindowPolicy(boolean forceNewWindow) {
+ this.forceNewWindow = forceNewWindow;
+ }
+}
diff --git a/source/edu/stanford/ejalbert/launching/windows/windowsConfig.properties b/source/edu/stanford/ejalbert/launching/windows/windowsConfig.properties
new file mode 100644
index 0000000..abdcd2e
--- /dev/null
+++ b/source/edu/stanford/ejalbert/launching/windows/windowsConfig.properties
@@ -0,0 +1,48 @@
+# ************************************************
+# Copyright 2006,2007 Jeff Chapman
+#
+# This file is part of BrowserLauncher2.
+#
+# BrowserLauncher2 is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# BrowserLauncher2 is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with BrowserLauncher2; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+# ************************************************
+# $Id: windowsConfig.properties,v 1.6 2007/08/30 19:38:09 jchapman0 Exp $
+
+# delimiter for browser listing
+delimchar=;
+
+# windows versions and arguments for launching a browser
+# command for starting default browser | command for starting a specific browser | use registry
+windows.winVista=cmd.exe /c start "" "<url>";"<path><browser>.exe" <args> "<url>";true
+windows.win2000=cmd.exe /c start "" "<url>";"<path><browser>.exe" <args> "<url>";true
+windows.win9x=command.com /c start "<url>";"<path><browser>.exe" <args> "<url>";true
+windows.winNT=cmd.exe /c start "" "<url>";"<path><browser>.exe" <args> "<url>";true
+
+# properties used to find browsers in program files folder
+program.files.template={0}:\\Program Files
+# drive letters to try when looking for Program Files folder
+drive.letters=C;D;E
+
+#windows.win2000=cmd.exe /c start "" "<url>";cmd.exe /c start <browser> <args> "<url>"
+#windows.win9x=command.com /c start "<url>";command.com /c start <browser> <args> "<url>"
+#windows.winNT=cmd.exe /c start "" "<url>";cmd.exe /c start <browser> <args> "<url>"
+
+# list of browsers and arguments for using them and discovering them
+# browser display name | browser exe name | new window argument | directory containing exe
+browser.mozilla=Mozilla;mozilla;;mozilla.org
+browser.netscape=Netscape;netscape;;Netscape
+browser.firefox=FireFox;firefox;-new-window;Mozilla Firefox
+browser.opera=Opera;opera;-newwindow;Opera
+browser.ie=IE;iexplore;;Internet Explorer
+browser.kmeleon=K-Meleon;k-meleon;;K-Meleon
diff --git a/source/edu/stanford/ejalbert/resources/Debugging.properties b/source/edu/stanford/ejalbert/resources/Debugging.properties
new file mode 100644
index 0000000..c80e945
--- /dev/null
+++ b/source/edu/stanford/ejalbert/resources/Debugging.properties
@@ -0,0 +1,59 @@
+# ************************************************
+# Copyright 2005 Jeff Chapman
+
+# This file is part of BrowserLauncher2.
+
+# BrowserLauncher2 is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+# BrowserLauncher2 is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public License
+# along with BrowserLauncher2; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+# ************************************************/
+# $Id: Debugging.properties,v 1.8 2007/01/31 18:31:22 jchapman0 Exp $
+
+# Resource file containing strings and other info for use by the Testing
+# tool.
+
+# initial message to display
+debug.mssg=\
+Please let us know the results of testing on your OS/Java configuration. The \
+information displayed below as well as any stack traces will be \
+helpful. Use the copy button to copy and paste the data into an email.
+
+# system properties to query and display, | and ; as separators
+# display|property.name;
+debug.propnames=\
+Java Version: |java.version;\
+Java Vendor: |java.vendor;\
+OS Name: |os.name;\
+OS Version: |os.version
+
+label.url=Enter a url:
+label.app.title=BrowserLauncher2 Test App 1.0
+label.logging.level=Logging Level:
+label.browser.list=Browser List:
+label.window.policy=Force New Window
+
+bttn.browse=Browse
+bttn.copy=Copy
+bttn.set.logging=Set Logging Level
+bttn.set.preference=Set Browser Preference
+
+logging.level.select.title=Logging Level Selection
+logging.level.select.message=Select a logging level from the list below
+
+url.default=file://localhost/
+
+# properties for logging interface
+logging.dateformat=yyyy-MM-dd HH:mm:ss,SSS
+
+logging.level.labels=DEBUG;INFO;WARN;ERROR
diff --git a/source/edu/stanford/ejalbert/testing/BrowserLauncherTestApp.java b/source/edu/stanford/ejalbert/testing/BrowserLauncherTestApp.java
new file mode 100644
index 0000000..5185d63
--- /dev/null
+++ b/source/edu/stanford/ejalbert/testing/BrowserLauncherTestApp.java
@@ -0,0 +1,349 @@
+/************************************************
+ Copyright 2004,2005,2006 Jeff Chapman
+
+ This file is part of BrowserLauncher2.
+
+ BrowserLauncher2 is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ BrowserLauncher2 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with BrowserLauncher2; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ ************************************************/
+// $Id: BrowserLauncherTestApp.java,v 1.22 2007/01/31 18:32:41 jchapman0 Exp $
+package edu.stanford.ejalbert.testing;
+
+import java.awt.BorderLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ResourceBundle;
+import java.util.StringTokenizer;
+import java.util.Arrays;
+import javax.swing.BorderFactory;
+import javax.swing.Box;
+import javax.swing.BoxLayout;
+import javax.swing.ComboBoxModel;
+import javax.swing.DefaultComboBoxModel;
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import javax.swing.JTextField;
+
+import edu.stanford.ejalbert.BrowserLauncher;
+import edu.stanford.ejalbert.exceptionhandler.BrowserLauncherErrorHandler;
+import java.awt.GridLayout;
+import java.util.List;
+import javax.swing.JCheckBox;
+import java.awt.event.ItemListener;
+import java.awt.event.ItemEvent;
+import edu.stanford.ejalbert.browserprefui.BrowserPrefAction;
+
+/**
+ * Standalone gui that allows for testing the broserlauncher code and provides
+ * a sample implementation.
+ *
+ * @author Jeff Chapman
+ */
+public class BrowserLauncherTestApp
+ extends JFrame {
+ private static final String debugResources =
+ "edu.stanford.ejalbert.resources.Debugging";
+ private TestAppLogger logger; // in ctor
+ private JComboBox browserBox = new JComboBox();
+ private JLabel loggingLevelTxtFld = new JLabel();
+ private JTextField urlTextField = new JTextField();
+ private BrowserLauncher launcher; // in ctor
+ private JTextArea debugTextArea = new JTextArea();
+ private JTextField browserListField = new JTextField();
+ private ResourceBundle bundle; // in ctor
+ private JCheckBox windowPolicyCBox = new JCheckBox();
+
+ public BrowserLauncherTestApp() {
+ super();
+ try {
+ bundle = ResourceBundle.getBundle(debugResources);
+ logger = initDebugLogging();
+ loggingLevelTxtFld.setText(logger.getLevelText());
+ super.setTitle(bundle.getString("label.app.title"));
+ populateDebugInfo(bundle, debugTextArea);
+ launcher = new BrowserLauncher(
+ logger,
+ new TestAppErrorHandler(debugTextArea));
+ ComboBoxModel cbModel = new DefaultComboBoxModel(launcher.
+ getBrowserList().toArray());
+ browserBox.setModel(cbModel);
+ windowPolicyCBox.setSelected(launcher.getNewWindowPolicy());
+ jbInit();
+ }
+ catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ private TestAppLogger initDebugLogging() {
+ String[] levelLabels =
+ bundle.getString("logging.level.labels").split(";");
+ debugTextArea.setEditable(false);
+ debugTextArea.setLineWrap(true);
+ debugTextArea.setWrapStyleWord(true);
+ debugTextArea.setText("");
+ return new TestAppLogger(debugTextArea,
+ levelLabels,
+ bundle.getString("logging.dateformat"));
+ }
+
+ public static void main(String[] args) {
+ BrowserLauncherTestApp app = new BrowserLauncherTestApp();
+ app.pack();
+ app.setVisible(true);
+ }
+
+ private void windowPolicyItemStateChange(ItemEvent e) {
+ launcher.setNewWindowPolicy(e.getStateChange() == ItemEvent.SELECTED);
+ }
+
+ private void populateDebugInfo(ResourceBundle bundle,
+ JTextArea debugTextArea) {
+ StringWriter stringWriter = new StringWriter();
+ PrintWriter printWriter = new PrintWriter(stringWriter, true);
+ // display first message
+ printWriter.println(bundle.getString("debug.mssg"));
+ printWriter.println();
+ // get property values to display
+ StringTokenizer tokenizer =
+ new StringTokenizer(bundle.getString("debug.propnames"),
+ ";",
+ false);
+ int pipeSymbol;
+ String token, display, property;
+ while (tokenizer.hasMoreTokens()) {
+ token = tokenizer.nextToken();
+ pipeSymbol = token.indexOf('|');
+ display = token.substring(0, pipeSymbol);
+ property = token.substring(pipeSymbol + 1);
+ printWriter.print(display);
+ printWriter.println(System.getProperty(property));
+ }
+ printWriter.close();
+ debugTextArea.append(stringWriter.toString());
+ }
+
+ private void jbInit()
+ throws Exception {
+ // button and action for setting the browser preference
+ BrowserPrefAction browserPrefAction = new BrowserPrefAction(
+ bundle.getString("bttn.set.preference"),
+ launcher,
+ this);
+ JButton prefBrowserBttn = new JButton(browserPrefAction);
+
+ JButton browseButton = new JButton(bundle.getString("bttn.browse"));
+ browseButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ browseButton_actionPerformed(e);
+ }
+ });
+ JLabel enterUrlLabel = new JLabel(bundle.getString("label.url"));
+ urlTextField.setText(bundle.getString("url.default"));
+ urlTextField.setColumns(25);
+ JPanel urlPanel = new JPanel(new BorderLayout());
+ urlPanel.add(enterUrlLabel, BorderLayout.LINE_START);
+ urlPanel.add(urlTextField, BorderLayout.CENTER);
+ urlPanel.add(browseButton, BorderLayout.LINE_END);
+
+ JScrollPane debugTextScrollPane = new JScrollPane(debugTextArea);
+ //debugTextScrollPane.getViewport().add(debugTextArea);
+
+ JLabel debugLevelLabel = new JLabel(bundle.getString(
+ "label.logging.level"));
+ JButton loggingLevelBttn = new JButton(bundle.getString(
+ "bttn.set.logging"));
+ loggingLevelBttn.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ loggingLevelBttn_actionPerformed(e);
+ }
+ });
+ JButton copyButton = new JButton(bundle.getString("bttn.copy"));
+ copyButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ copyButton_actionPerformed(e);
+ }
+ });
+ JPanel debugTextBttnPanel = new JPanel();
+ BoxLayout bttnBoxLayout = new BoxLayout(
+ debugTextBttnPanel,
+ BoxLayout.X_AXIS);
+ debugTextBttnPanel.setLayout(bttnBoxLayout);
+ debugTextBttnPanel.add(Box.createHorizontalStrut(2));
+ debugTextBttnPanel.add(browserBox);
+ debugTextBttnPanel.add(Box.createHorizontalStrut(2));
+ debugTextBttnPanel.add(debugLevelLabel);
+ debugTextBttnPanel.add(Box.createHorizontalStrut(3));
+ debugTextBttnPanel.add(loggingLevelTxtFld);
+ debugTextBttnPanel.add(Box.createHorizontalStrut(5));
+ debugTextBttnPanel.add(Box.createHorizontalGlue());
+ debugTextBttnPanel.add(loggingLevelBttn);
+ debugTextBttnPanel.add(Box.createHorizontalStrut(3));
+ debugTextBttnPanel.add(copyButton);
+ debugTextBttnPanel.add(Box.createHorizontalStrut(2));
+
+ windowPolicyCBox.addItemListener(new ItemListener() {
+ public void itemStateChanged(ItemEvent e) {
+ windowPolicyItemStateChange(e);
+ }
+ });
+ windowPolicyCBox.setText(bundle.getString("label.window.policy"));
+ JLabel browserListLabel = new JLabel(bundle.getString(
+ "label.browser.list"));
+ JPanel browserListPanel = new JPanel();
+ BoxLayout browserListBoxLayout = new BoxLayout(
+ browserListPanel,
+ BoxLayout.X_AXIS);
+ browserListPanel.setLayout(browserListBoxLayout);
+ browserListPanel.add(browserListLabel);
+ browserListPanel.add(Box.createHorizontalStrut(2));
+ browserListPanel.add(browserListField);
+ browserListPanel.add(Box.createHorizontalStrut(2));
+ browserListPanel.add(windowPolicyCBox);
+ browserListPanel.add(Box.createHorizontalStrut(2));
+ browserListPanel.add(prefBrowserBttn);
+
+ JPanel configPanel = new JPanel(new GridLayout(2, 1, 0, 2));
+ configPanel.add(browserListPanel);
+ configPanel.add(debugTextBttnPanel);
+
+ JPanel mainPanel = new JPanel(new BorderLayout());
+ mainPanel.setBorder(BorderFactory.createEmptyBorder(2, 5, 2, 3));
+ mainPanel.add(debugTextScrollPane,
+ java.awt.BorderLayout.CENTER);
+ mainPanel.add(urlPanel,
+ java.awt.BorderLayout.NORTH);
+ mainPanel.add(configPanel,
+ java.awt.BorderLayout.SOUTH);
+
+ this.getContentPane().add(mainPanel);
+ getRootPane().setDefaultButton(browseButton);
+ setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ }
+
+ private static void updateDebugTextArea(Exception exception,
+ JTextArea debugTextArea) {
+ StringWriter stringWriter = new StringWriter();
+ PrintWriter printWriter = new PrintWriter(stringWriter, true);
+ printWriter.println();
+ exception.printStackTrace(printWriter);
+ printWriter.println();
+ printWriter.close();
+ debugTextArea.append(stringWriter.toString());
+ }
+
+ private void browseButton_actionPerformed(ActionEvent e) {
+ if (logger.isInfoEnabled()) {
+ logger.info("browse button clicked");
+ }
+ try {
+ String urlString = urlTextField.getText();
+ if (urlString == null || urlString.trim().length() == 0) {
+ throw new MalformedURLException("You must specify a url.");
+ }
+ new URL(urlString); // may throw MalformedURLException
+ BrowserLauncherErrorHandler errorHandler = new TestAppErrorHandler(
+ debugTextArea);
+ // use browser list if browserListField has data
+ String browserItems = browserListField.getText();
+ if (browserItems != null && browserItems.length() > 0) {
+ logger.debug("using browser list");
+ String[] browserArray = browserItems.split("[ ]+");
+ List browserList = Arrays.asList(browserArray);
+ logger.debug(browserList.toString());
+ launcher.openURLinBrowser(browserList,
+ urlString);
+ }
+ else {
+ String targetBrowser = browserBox.getSelectedItem().toString();
+ logger.debug(targetBrowser);
+ launcher.openURLinBrowser(targetBrowser,
+ urlString);
+ }
+ }
+ catch (Exception ex) {
+ // capture exception
+ BrowserLauncherTestApp.updateDebugTextArea(ex, debugTextArea);
+ // show message to user
+ JOptionPane.showMessageDialog(this,
+ ex.getMessage(),
+ "Error Message",
+ JOptionPane.ERROR_MESSAGE);
+ }
+ }
+
+ private void copyButton_actionPerformed(ActionEvent e) {
+ if (logger.isInfoEnabled()) {
+ logger.info("copy button clicked");
+ }
+ debugTextArea.selectAll();
+ debugTextArea.copy();
+ debugTextArea.select(0, 0);
+ }
+
+ private void loggingLevelBttn_actionPerformed(ActionEvent e) {
+ String[] levels = logger.getLevelOptions();
+ int levelIndex = logger.getLevel();
+ String level = (String) JOptionPane.showInputDialog(
+ this,
+ bundle.getString("logging.level.select.message"),
+ bundle.getString("logging.level.select.title"),
+ JOptionPane.QUESTION_MESSAGE,
+ null,
+ levels,
+ levels[levelIndex]);
+ if (level != null && level.length() > 0) {
+ levelIndex = -1;
+ for (int idx = 0, max = levels.length;
+ idx < max && levelIndex == -1; idx++) {
+ if (level.equals(levels[idx])) {
+ levelIndex = idx;
+ }
+
+ }
+ logger.setLevel(levelIndex);
+ loggingLevelTxtFld.setText(logger.getLevelText());
+ }
+ }
+
+ private static class TestAppErrorHandler
+ implements BrowserLauncherErrorHandler {
+ private JTextArea debugTextArea; // in ctor
+
+ TestAppErrorHandler(JTextArea debugTextArea) {
+ this.debugTextArea = debugTextArea;
+ }
+
+ public void handleException(Exception ex) {
+ // capture exception
+ BrowserLauncherTestApp.updateDebugTextArea(ex, debugTextArea);
+ // show message to user
+ JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),
+ ex.getMessage(),
+ "Error Message",
+ JOptionPane.ERROR_MESSAGE);
+ }
+ }
+}
diff --git a/source/edu/stanford/ejalbert/testing/TestAppLogger.java b/source/edu/stanford/ejalbert/testing/TestAppLogger.java
new file mode 100644
index 0000000..d9a2344
--- /dev/null
+++ b/source/edu/stanford/ejalbert/testing/TestAppLogger.java
@@ -0,0 +1,107 @@
+/************************************************
+ Copyright 2005,2006 Jeff Chapman
+
+ This file is part of BrowserLauncher2.
+
+ BrowserLauncher2 is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ BrowserLauncher2 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with BrowserLauncher2; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ ************************************************/
+// $Id: TestAppLogger.java,v 1.3 2006/03/23 20:55:14 jchapman0 Exp $
+package edu.stanford.ejalbert.testing;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import javax.swing.JTextArea;
+
+import net.sf.wraplog.AbstractLogger;
+import net.sf.wraplog.Level;
+
+/**
+ * Implements a logger for the test application. The log messages
+ * are sent to a JTextArea.
+ */
+class TestAppLogger
+ extends AbstractLogger {
+ private JTextArea debugTextArea; // in ctor
+ private String[] levelText; // in ctor
+ private SimpleDateFormat format; // in ctor =
+
+ public TestAppLogger(JTextArea debugTextArea,
+ String[] levelLabels,
+ String dateFormat) {
+ super();
+ this.debugTextArea = debugTextArea;
+ this.levelText = levelLabels;
+ this.format = new SimpleDateFormat(dateFormat);
+ }
+
+ /**
+ * Logs a message and optional error details.
+ *
+ * @param logLevel one of: Level.DEBUG, Level.INFO, Level.WARN,
+ * Level.ERROR
+ * @param message the actual message; this will never be
+ * <code>null</code>
+ * @param error an error that is related to the message; unless
+ * <code>null</code>, the name and stack trace of the error are logged
+ * @throws Exception
+ * @todo Implement this net.sf.wraplog.AbstractLogger method
+ */
+ protected void reallyLog(int logLevel,
+ String message,
+ Throwable error)
+ throws Exception {
+ if (message == null) {
+ message = "null";
+ }
+ StringWriter stringWriter = new StringWriter();
+ PrintWriter printWriter = new PrintWriter(stringWriter, true);
+ String threadName = Thread.currentThread().getName();
+ String dateAndTime = format.format(new Date());
+ printWriter.println(dateAndTime + " [" + threadName + "] "
+ + getLevelText(logLevel) + " " + message);
+ if (error != null) {
+ error.printStackTrace(printWriter);
+ }
+ printWriter.println();
+ printWriter.close();
+ debugTextArea.append(stringWriter.toString());
+ }
+
+ public String getLevelText() {
+ return getLevelText(getLevel());
+ }
+
+ public String[] getLevelOptions() {
+ return levelText;
+ }
+
+ /**
+ * Return text that represents <code>logLevel</code>.
+ */
+ private String getLevelText(int logLevel) {
+ if (logLevel < Level.DEBUG || logLevel > Level.ERROR) {
+ throw new IllegalArgumentException(
+ "logLevel must be one of those defined in net.sf.warplog.Level, but is "
+ + Integer.toString(logLevel));
+ }
+ else {
+ return levelText[logLevel];
+ }
+ }
+}
diff --git a/source/net/sf/wraplog/AbstractLogger.java b/source/net/sf/wraplog/AbstractLogger.java
new file mode 100644
index 0000000..3788e0f
--- /dev/null
+++ b/source/net/sf/wraplog/AbstractLogger.java
@@ -0,0 +1,167 @@
+//Copyright (c) 2005, Thomas Aglassinger
+//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.
+//
+// * Neither the name of the author nor the names of its contributors
+//may be used to endorse or promote products derived from this software
+//without specific prior written permission.
+//
+//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 OWNER 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 net.sf.wraplog;
+
+/**
+ * Abstract base class to write messages about interesting things happening to a
+ * log.
+ * <p>
+ * Updated to WrapLog version 1.1.
+ *
+ * @author Thomas Aglassinger
+ */
+public abstract class AbstractLogger {
+
+ private int level = Level.DEBUG;
+
+ private int loggedMessageCount;
+
+ protected void checkLevel(int logLevel, String name) {
+ String actualName;
+ if (name == null) {
+ actualName = "level";
+ }
+ else {
+ actualName = name;
+ }
+ if ((logLevel < Level.DEBUG) || (logLevel > Level.ERROR)) {
+ throw new IllegalArgumentException(actualName
+ +
+ " must be one of: Level.DEBUG, Level.INFO, Level.WARN, Level.ERROR");
+ }
+ }
+
+ public void debug(String message) {
+ debug(message, null);
+ }
+
+ public void debug(String message, Throwable error) {
+ log(Level.DEBUG, message, error);
+ }
+
+ public void error(String message) {
+ error(message, null);
+ }
+
+ public void error(String message, Throwable error) {
+ log(Level.ERROR, message, error);
+ }
+
+ public int getLevel() {
+ return level;
+ }
+
+ /** Count of how many messages have been logged. */
+ public int getLoggedMessageCount() {
+ return loggedMessageCount;
+ }
+
+ public void info(String message) {
+ info(message, null);
+ }
+
+ public void info(String message, Throwable error) {
+ log(Level.INFO, message, error);
+ }
+
+ public boolean isEnabled(int logLevel) {
+ checkLevel(level, null);
+ return logLevel >= level;
+ }
+
+ /**
+ * Logs a message and optional error details.
+ *
+ * @param logLevel one of: Level.DEBUG, Level.INFO, Level.WARN, Level.ERROR
+ * @param message the actual message; this will never be <code>null</code>
+ * @param error an error that is related to the message; unless <code>null</code>, the name and stack trace of the error are logged
+ */
+ protected abstract void reallyLog(int logLevel, String message,
+ Throwable error)
+ throws Exception;
+
+ /**
+ * Provided that <code>getLevel()</code> accepts it, log
+ * <code>message</code>. Otherwise, do nothing.
+ */
+ public void log(int logLevel, String message) {
+ log(logLevel, message, null);
+ }
+
+ /**
+ * Provided that <code>getLevel()</code> accepts it, log
+ * <code>message</code> and <code>error</code>. Otherwise, do nothing.
+ */
+ public void log(int logLevel, String message, Throwable error) {
+ if (isEnabled(logLevel)) {
+ try {
+ reallyLog(logLevel, message, error);
+ loggedMessageCount += 1;
+ }
+ catch (Exception error2) {
+ throw new LoggingException("cannot log message: " + message,
+ error2);
+ }
+ }
+ }
+
+ public void setLevel(int newLevel) {
+ if ((level >= Level.DEBUG) || (level <= Level.ERROR)) {
+ level = newLevel;
+ }
+ else {
+ throw new IllegalArgumentException(
+ "newLevel must be one of: Level.DEBUG, Level.INFO, Level.WARN, Level.ERROR");
+ }
+ }
+
+ public void warn(String message) {
+ warn(message, null);
+ }
+
+ public boolean isDebugEnabled() {
+ return isEnabled(Level.DEBUG);
+ }
+
+ public boolean isInfoEnabled() {
+ return isEnabled(Level.INFO);
+ }
+
+ public boolean isWarnEnabled() {
+ return isEnabled(Level.WARN);
+ }
+
+ public boolean isErrorEnabled() {
+ return isEnabled(Level.ERROR);
+ }
+
+ public void warn(String message, Throwable error) {
+ log(Level.WARN, message, error);
+ }
+}
diff --git a/source/net/sf/wraplog/Level.java b/source/net/sf/wraplog/Level.java
new file mode 100644
index 0000000..bfedbd4
--- /dev/null
+++ b/source/net/sf/wraplog/Level.java
@@ -0,0 +1,76 @@
+//Copyright (c) 2005, Thomas Aglassinger
+//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.
+//
+// * Neither the name of the author nor the names of its contributors
+//may be used to endorse or promote products derived from this software
+//without specific prior written permission.
+//
+//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 OWNER 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 net.sf.wraplog;
+
+/**
+ * Declaration of different logging levels.
+ * <p>
+ * Updated to WrapLog version 1.1.
+ *
+ * @author Thomas Aglassinger
+ */
+public class Level {
+ /** Logging level for messages that usually are of no interest for the user. */
+ public static final int DEBUG = 0;
+
+ /**
+ * Logging level for messages that explain why the desired operation cannot
+ * be performed.
+ * <p>
+ * Note: a simple way for deriving goog error messages is to make them fit
+ * the pattern: <blockquote>cannot do something: actual state must match
+ * expectation. </blockquote> Just fill in "do something", "actual state"
+ * and "expectation".<p> In case your code is just reporting a Java
+ * <code>Exception</code> that happens at a lower level on the call stack,
+ * use the pattern: <blockquote>cannot do something: <
+ * <code>exception.getMessage()</code> >. </blockquote> In practice,
+ * this often results into sucky error messages, but therer is not much you
+ * can do about it except making sure that if your own
+ * <code>Exceptions</code> have a useful <code>getMessage()</code>.
+ */
+ public static final int ERROR = 3;
+
+ /**
+ * Logging level for messages that tell details about normal operations
+ * currently going on.
+ */
+ public static final int INFO = 1;
+
+ /**
+ * Logging level for message that notify that the things can be processed,
+ * but the user might want to take a closer look at the current situation.
+ * <p>
+ * Note: warnings are a good indicator for bad design. They hint at the
+ * developer being to dumb to resolve a situation and therefor delegating
+ * the responsibility to the user. Preferrably, the code shoud be changed to
+ * either log <code>INFO</code>, throw an exception or log
+ * <code>ERROR</code>.
+ */
+ public static final int WARN = 2;
+}
diff --git a/source/net/sf/wraplog/Logger.java b/source/net/sf/wraplog/Logger.java
new file mode 100644
index 0000000..5d39487
--- /dev/null
+++ b/source/net/sf/wraplog/Logger.java
@@ -0,0 +1,70 @@
+//Copyright (c) 2005, Thomas Aglassinger
+//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.
+ //
+ //* Neither the name of the author nor the names of its contributors
+ //may be used to endorse or promote products derived from this software
+ //without specific prior written permission.
+ //
+ //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 OWNER 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 net.sf.wraplog;
+
+/**
+ * This class is not included in WrapLog version 1.1.
+ * <p>
+ * Updated to WrapLog version 1.1.
+ *
+ * @deprecated -- this class is no longer part of WrapLog.
+ * @version 1.0
+ */
+public class Logger
+ extends SystemLogger {
+ private static Logger logger;
+
+ private static synchronized Logger getLogger() {
+ if (logger == null) {
+ logger = new Logger();
+ }
+ return logger;
+ }
+
+ /**
+ * @deprecated
+ * @param name String
+ * @return Logger
+ */
+ public static Logger getLogger(String name) {
+ return getLogger();
+ }
+
+ /**
+ * @deprecated
+ * @param clazz Class
+ * @return Logger
+ */
+ public static Logger getLogger(Class clazz) {
+ if (clazz == null) {
+ throw new NullPointerException("parameter clazz must not be null");
+ }
+ return getLogger(clazz.getName());
+ }
+}
diff --git a/source/net/sf/wraplog/LoggingException.java b/source/net/sf/wraplog/LoggingException.java
new file mode 100644
index 0000000..4e51240
--- /dev/null
+++ b/source/net/sf/wraplog/LoggingException.java
@@ -0,0 +1,46 @@
+//Copyright (c) 2005, Thomas Aglassinger
+//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.
+//
+// * Neither the name of the author nor the names of its contributors
+//may be used to endorse or promote products derived from this software
+//without specific prior written permission.
+//
+//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 OWNER 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 net.sf.wraplog;
+
+/**
+ * RuntimeException to indicate that a message could not be logged.
+ * <p>
+ * Updated to WrapLog version 1.1.
+ *
+ * @author Thomas Aglassinger
+ */
+public class LoggingException
+ extends RuntimeException {
+ public LoggingException(String newMessage, Throwable cause) {
+ super(newMessage);
+ if (cause != null) {
+ initCause(cause);
+ }
+ }
+}
diff --git a/source/net/sf/wraplog/NoneLogger.java b/source/net/sf/wraplog/NoneLogger.java
new file mode 100644
index 0000000..cca5692
--- /dev/null
+++ b/source/net/sf/wraplog/NoneLogger.java
@@ -0,0 +1,52 @@
+//Copyright (c) 2005, Thomas Aglassinger
+//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.
+//
+// * Neither the name of the author nor the names of its contributors
+//may be used to endorse or promote products derived from this software
+//without specific prior written permission.
+//
+//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 OWNER 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 net.sf.wraplog;
+
+/**
+ * A Logger that does not log anywhere. This is a useful a an internal default
+ * for libraries before the client applications sets a logger.
+ * <p>
+ * Updated to WrapLog version 1.1.
+ *
+ * @author Thomas Aglassinger
+ */
+public class NoneLogger
+ extends AbstractLogger {
+
+ /**
+ * Does nothing. Messages are ignored.
+ *
+ * @see net.sf.wraplog.AbstractLogger#reallyLog(int, java.lang.String,
+ * java.lang.Throwable)
+ */
+ protected void reallyLog(int logLevel, String message, Throwable error) {
+ // do nothing
+ }
+
+}
diff --git a/source/net/sf/wraplog/SystemLogger.java b/source/net/sf/wraplog/SystemLogger.java
new file mode 100644
index 0000000..6f8cc4c
--- /dev/null
+++ b/source/net/sf/wraplog/SystemLogger.java
@@ -0,0 +1,101 @@
+//Copyright (c) 2005, Thomas Aglassinger
+//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.
+//
+// * Neither the name of the author nor the names of its contributors
+//may be used to endorse or promote products derived from this software
+//without specific prior written permission.
+//
+//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 OWNER 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 net.sf.wraplog;
+
+import java.io.PrintStream;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * Logger to write messages to <code>System.out</code> (debug, info) and
+ * <code>System.err</code> (warn, error).
+ * <p>
+ * Updated to WrapLog version 1.1.
+ *
+ * @see System#err
+ * @see System#out
+ * @author Thomas Aglassinger
+ */
+//$Id: SystemLogger.java,v 1.3 2005/12/14 16:07:22 jchapman0 Exp $
+public class SystemLogger
+ extends AbstractLogger {
+
+ private SimpleDateFormat format = new SimpleDateFormat(
+ "yyyy-MM-dd HH:mm:ss,SSS");
+ /* (non-Javadoc)
+ * @see edu.stanford.ejalbert.logging.Logger#log(int, java.lang.String, java.lang.Throwable)
+ */
+ protected void reallyLog(int logLevel, String message, Throwable error) {
+ PrintStream stream;
+ if (logLevel < Level.WARN) {
+ stream = System.out;
+ }
+ else {
+ stream = System.err;
+ }
+ if (message == null) {
+ throw new NullPointerException("message must not be null");
+ }
+ if (stream == null) {
+ throw new NullPointerException("stream must not be null");
+ }
+ String threadName = Thread.currentThread().getName();
+ String dateAndTime = format.format(new Date());
+ stream.println(dateAndTime + " [" + threadName + "] "
+ + getLevelText(logLevel) + " " + message);
+ if (error != null) {
+ error.printStackTrace(stream);
+ }
+ }
+
+ /**
+ * Return a text that represents <code>logLevel</code>.
+ */
+ protected String getLevelText(int logLevel) {
+ String result;
+ if (logLevel == Level.DEBUG) {
+ result = "DEBUG";
+ }
+ else if (logLevel == Level.INFO) {
+ result = "INFO ";
+ }
+ else if (logLevel == Level.WARN) {
+ result = "WARN ";
+ }
+ else if (logLevel == Level.ERROR) {
+ result = "ERROR";
+ }
+ else {
+ throw new IllegalArgumentException(
+ "logLevel must be one of those defined in net.sf.warplog.Level, but is "
+ + logLevel);
+ }
+ return result;
+ }
+}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/libbrowserlauncher-java.git
More information about the pkg-java-commits
mailing list