Compare commits

..

5 Commits

Author SHA1 Message Date
beard%netscape.com
d30ae9fd55 commented out code that sets prototype of JavaAdapter instance, which broke calls to Java methods, toString(), etc.
git-svn-id: svn://10.0.0.236/branches/ClassGen_BRANCH@48180 18797224-902f-48f8-a5cc-f745e15eee43
1999-09-18 07:55:31 +00:00
norris%netscape.com
14b0e9035d Avoid throwing exception for NervousText.
git-svn-id: svn://10.0.0.236/branches/ClassGen_BRANCH@48005 18797224-902f-48f8-a5cc-f745e15eee43
1999-09-17 20:18:27 +00:00
beard%netscape.com
0e53f7d205 copy all of the arguments, instead of 1..(args.length-1)
git-svn-id: svn://10.0.0.236/branches/ClassGen_BRANCH@47891 18797224-902f-48f8-a5cc-f745e15eee43
1999-09-17 01:06:22 +00:00
norris%netscape.com
b6c0881d76 Changes for the NervousText applet example.
git-svn-id: svn://10.0.0.236/branches/ClassGen_BRANCH@46577 18797224-902f-48f8-a5cc-f745e15eee43
1999-09-09 17:57:58 +00:00
(no author)
7144ca2ee4 This commit was manufactured by cvs2svn to create branch 'ClassGen_BRANCH'.
git-svn-id: svn://10.0.0.236/branches/ClassGen_BRANCH@44416 18797224-902f-48f8-a5cc-f745e15eee43
1999-08-25 01:05:43 +00:00
427 changed files with 55140 additions and 102702 deletions

View File

@@ -1,851 +0,0 @@
The majority of Rhino is MPL 1.1 / GPL 2.0 dual licensed:
The Mozilla Public License (http://www.mozilla.org/MPL/MPL-1.1.txt):
============================================================================
MOZILLA PUBLIC LICENSE
Version 1.1
---------------
1. Definitions.
1.0.1. "Commercial Use" means distribution or otherwise making the
Covered Code available to a third party.
1.1. "Contributor" means each entity that creates or contributes to
the creation of Modifications.
1.2. "Contributor Version" means the combination of the Original
Code, prior Modifications used by a Contributor, and the Modifications
made by that particular Contributor.
1.3. "Covered Code" means the Original Code or Modifications or the
combination of the Original Code and Modifications, in each case
including portions thereof.
1.4. "Electronic Distribution Mechanism" means a mechanism generally
accepted in the software development community for the electronic
transfer of data.
1.5. "Executable" means Covered Code in any form other than Source
Code.
1.6. "Initial Developer" means the individual or entity identified
as the Initial Developer in the Source Code notice required by Exhibit
A.
1.7. "Larger Work" means a work which combines Covered Code or
portions thereof with code not governed by the terms of this License.
1.8. "License" means this document.
1.8.1. "Licensable" means having the right to grant, to the maximum
extent possible, whether at the time of the initial grant or
subsequently acquired, any and all of the rights conveyed herein.
1.9. "Modifications" means any addition to or deletion from the
substance or structure of either the Original Code or any previous
Modifications. When Covered Code is released as a series of files, a
Modification is:
A. Any addition to or deletion from the contents of a file
containing Original Code or previous Modifications.
B. Any new file that contains any part of the Original Code or
previous Modifications.
1.10. "Original Code" means Source Code of computer software code
which is described in the Source Code notice required by Exhibit A as
Original Code, and which, at the time of its release under this
License is not already Covered Code governed by this License.
1.10.1. "Patent Claims" means any patent claim(s), now owned or
hereafter acquired, including without limitation, method, process,
and apparatus claims, in any patent Licensable by grantor.
1.11. "Source Code" means the preferred form of the Covered Code for
making modifications to it, including all modules it contains, plus
any associated interface definition files, scripts used to control
compilation and installation of an Executable, or source code
differential comparisons against either the Original Code or another
well known, available Covered Code of the Contributor's choice. The
Source Code can be in a compressed or archival form, provided the
appropriate decompression or de-archiving software is widely available
for no charge.
1.12. "You" (or "Your") means an individual or a legal entity
exercising rights under, and complying with all of the terms of, this
License or a future version of this License issued under Section 6.1.
For legal entities, "You" includes any entity which controls, is
controlled by, or is under common control with You. For purposes of
this definition, "control" means (a) the power, direct or indirect,
to cause the direction or management of such entity, whether by
contract or otherwise, or (b) ownership of more than fifty percent
(50%) of the outstanding shares or beneficial ownership of such
entity.
2. Source Code License.
2.1. The Initial Developer Grant.
The Initial Developer hereby grants You a world-wide, royalty-free,
non-exclusive license, subject to third party intellectual property
claims:
(a) under intellectual property rights (other than patent or
trademark) Licensable by Initial Developer to use, reproduce,
modify, display, perform, sublicense and distribute the Original
Code (or portions thereof) with or without Modifications, and/or
as part of a Larger Work; and
(b) under Patents Claims infringed by the making, using or
selling of Original Code, to make, have made, use, practice,
sell, and offer for sale, and/or otherwise dispose of the
Original Code (or portions thereof).
(c) the licenses granted in this Section 2.1(a) and (b) are
effective on the date Initial Developer first distributes
Original Code under the terms of this License.
(d) Notwithstanding Section 2.1(b) above, no patent license is
granted: 1) for code that You delete from the Original Code; 2)
separate from the Original Code; or 3) for infringements caused
by: i) the modification of the Original Code or ii) the
combination of the Original Code with other software or devices.
2.2. Contributor Grant.
Subject to third party intellectual property claims, each Contributor
hereby grants You a world-wide, royalty-free, non-exclusive license
(a) under intellectual property rights (other than patent or
trademark) Licensable by Contributor, to use, reproduce, modify,
display, perform, sublicense and distribute the Modifications
created by such Contributor (or portions thereof) either on an
unmodified basis, with other Modifications, as Covered Code
and/or as part of a Larger Work; and
(b) under Patent Claims infringed by the making, using, or
selling of Modifications made by that Contributor either alone
and/or in combination with its Contributor Version (or portions
of such combination), to make, use, sell, offer for sale, have
made, and/or otherwise dispose of: 1) Modifications made by that
Contributor (or portions thereof); and 2) the combination of
Modifications made by that Contributor with its Contributor
Version (or portions of such combination).
(c) the licenses granted in Sections 2.2(a) and 2.2(b) are
effective on the date Contributor first makes Commercial Use of
the Covered Code.
(d) Notwithstanding Section 2.2(b) above, no patent license is
granted: 1) for any code that Contributor has deleted from the
Contributor Version; 2) separate from the Contributor Version;
3) for infringements caused by: i) third party modifications of
Contributor Version or ii) the combination of Modifications made
by that Contributor with other software (except as part of the
Contributor Version) or other devices; or 4) under Patent Claims
infringed by Covered Code in the absence of Modifications made by
that Contributor.
3. Distribution Obligations.
3.1. Application of License.
The Modifications which You create or to which You contribute are
governed by the terms of this License, including without limitation
Section 2.2. The Source Code version of Covered Code may be
distributed only under the terms of this License or a future version
of this License released under Section 6.1, and You must include a
copy of this License with every copy of the Source Code You
distribute. You may not offer or impose any terms on any Source Code
version that alters or restricts the applicable version of this
License or the recipients' rights hereunder. However, You may include
an additional document offering the additional rights described in
Section 3.5.
3.2. Availability of Source Code.
Any Modification which You create or to which You contribute must be
made available in Source Code form under the terms of this License
either on the same media as an Executable version or via an accepted
Electronic Distribution Mechanism to anyone to whom you made an
Executable version available; and if made available via Electronic
Distribution Mechanism, must remain available for at least twelve (12)
months after the date it initially became available, or at least six
(6) months after a subsequent version of that particular Modification
has been made available to such recipients. You are responsible for
ensuring that the Source Code version remains available even if the
Electronic Distribution Mechanism is maintained by a third party.
3.3. Description of Modifications.
You must cause all Covered Code to which You contribute to contain a
file documenting the changes You made to create that Covered Code and
the date of any change. You must include a prominent statement that
the Modification is derived, directly or indirectly, from Original
Code provided by the Initial Developer and including the name of the
Initial Developer in (a) the Source Code, and (b) in any notice in an
Executable version or related documentation in which You describe the
origin or ownership of the Covered Code.
3.4. Intellectual Property Matters
(a) Third Party Claims.
If Contributor has knowledge that a license under a third party's
intellectual property rights is required to exercise the rights
granted by such Contributor under Sections 2.1 or 2.2,
Contributor must include a text file with the Source Code
distribution titled "LEGAL" which describes the claim and the
party making the claim in sufficient detail that a recipient will
know whom to contact. If Contributor obtains such knowledge after
the Modification is made available as described in Section 3.2,
Contributor shall promptly modify the LEGAL file in all copies
Contributor makes available thereafter and shall take other steps
(such as notifying appropriate mailing lists or newsgroups)
reasonably calculated to inform those who received the Covered
Code that new knowledge has been obtained.
(b) Contributor APIs.
If Contributor's Modifications include an application programming
interface and Contributor has knowledge of patent licenses which
are reasonably necessary to implement that API, Contributor must
also include this information in the LEGAL file.
(c) Representations.
Contributor represents that, except as disclosed pursuant to
Section 3.4(a) above, Contributor believes that Contributor's
Modifications are Contributor's original creation(s) and/or
Contributor has sufficient rights to grant the rights conveyed by
this License.
3.5. Required Notices.
You must duplicate the notice in Exhibit A in each file of the Source
Code. If it is not possible to put such notice in a particular Source
Code file due to its structure, then You must include such notice in a
location (such as a relevant directory) where a user would be likely
to look for such a notice. If You created one or more Modification(s)
You may add your name as a Contributor to the notice described in
Exhibit A. You must also duplicate this License in any documentation
for the Source Code where You describe recipients' rights or ownership
rights relating to Covered Code. You may choose to offer, and to
charge a fee for, warranty, support, indemnity or liability
obligations to one or more recipients of Covered Code. However, You
may do so only on Your own behalf, and not on behalf of the Initial
Developer or any Contributor. You must make it absolutely clear than
any such warranty, support, indemnity or liability obligation is
offered by You alone, and You hereby agree to indemnify the Initial
Developer and every Contributor for any liability incurred by the
Initial Developer or such Contributor as a result of warranty,
support, indemnity or liability terms You offer.
3.6. Distribution of Executable Versions.
You may distribute Covered Code in Executable form only if the
requirements of Section 3.1-3.5 have been met for that Covered Code,
and if You include a notice stating that the Source Code version of
the Covered Code is available under the terms of this License,
including a description of how and where You have fulfilled the
obligations of Section 3.2. The notice must be conspicuously included
in any notice in an Executable version, related documentation or
collateral in which You describe recipients' rights relating to the
Covered Code. You may distribute the Executable version of Covered
Code or ownership rights under a license of Your choice, which may
contain terms different from this License, provided that You are in
compliance with the terms of this License and that the license for the
Executable version does not attempt to limit or alter the recipient's
rights in the Source Code version from the rights set forth in this
License. If You distribute the Executable version under a different
license You must make it absolutely clear that any terms which differ
from this License are offered by You alone, not by the Initial
Developer or any Contributor. You hereby agree to indemnify the
Initial Developer and every Contributor for any liability incurred by
the Initial Developer or such Contributor as a result of any such
terms You offer.
3.7. Larger Works.
You may create a Larger Work by combining Covered Code with other code
not governed by the terms of this License and distribute the Larger
Work as a single product. In such a case, You must make sure the
requirements of this License are fulfilled for the Covered Code.
4. Inability to Comply Due to Statute or Regulation.
If it is impossible for You to comply with any of the terms of this
License with respect to some or all of the Covered Code due to
statute, judicial order, or regulation then You must: (a) comply with
the terms of this License to the maximum extent possible; and (b)
describe the limitations and the code they affect. Such description
must be included in the LEGAL file described in Section 3.4 and must
be included with all distributions of the Source Code. Except to the
extent prohibited by statute or regulation, such description must be
sufficiently detailed for a recipient of ordinary skill to be able to
understand it.
5. Application of this License.
This License applies to code to which the Initial Developer has
attached the notice in Exhibit A and to related Covered Code.
6. Versions of the License.
6.1. New Versions.
Netscape Communications Corporation ("Netscape") may publish revised
and/or new versions of the License from time to time. Each version
will be given a distinguishing version number.
6.2. Effect of New Versions.
Once Covered Code has been published under a particular version of the
License, You may always continue to use it under the terms of that
version. You may also choose to use such Covered Code under the terms
of any subsequent version of the License published by Netscape. No one
other than Netscape has the right to modify the terms applicable to
Covered Code created under this License.
6.3. Derivative Works.
If You create or use a modified version of this License (which you may
only do in order to apply it to code which is not already Covered Code
governed by this License), You must (a) rename Your license so that
the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape",
"MPL", "NPL" or any confusingly similar phrase do not appear in your
license (except to note that your license differs from this License)
and (b) otherwise make it clear that Your version of the license
contains terms which differ from the Mozilla Public License and
Netscape Public License. (Filling in the name of the Initial
Developer, Original Code or Contributor in the notice described in
Exhibit A shall not of themselves be deemed to be modifications of
this License.)
7. DISCLAIMER OF WARRANTY.
COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF
DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING.
THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE
IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT,
YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE
COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER
OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF
ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
8. TERMINATION.
8.1. This License and the rights granted hereunder will terminate
automatically if You fail to comply with terms herein and fail to cure
such breach within 30 days of becoming aware of the breach. All
sublicenses to the Covered Code which are properly granted shall
survive any termination of this License. Provisions which, by their
nature, must remain in effect beyond the termination of this License
shall survive.
8.2. If You initiate litigation by asserting a patent infringement
claim (excluding declatory judgment actions) against Initial Developer
or a Contributor (the Initial Developer or Contributor against whom
You file such action is referred to as "Participant") alleging that:
(a) such Participant's Contributor Version directly or indirectly
infringes any patent, then any and all rights granted by such
Participant to You under Sections 2.1 and/or 2.2 of this License
shall, upon 60 days notice from Participant terminate prospectively,
unless if within 60 days after receipt of notice You either: (i)
agree in writing to pay Participant a mutually agreeable reasonable
royalty for Your past and future use of Modifications made by such
Participant, or (ii) withdraw Your litigation claim with respect to
the Contributor Version against such Participant. If within 60 days
of notice, a reasonable royalty and payment arrangement are not
mutually agreed upon in writing by the parties or the litigation claim
is not withdrawn, the rights granted by Participant to You under
Sections 2.1 and/or 2.2 automatically terminate at the expiration of
the 60 day notice period specified above.
(b) any software, hardware, or device, other than such Participant's
Contributor Version, directly or indirectly infringes any patent, then
any rights granted to You by such Participant under Sections 2.1(b)
and 2.2(b) are revoked effective as of the date You first made, used,
sold, distributed, or had made, Modifications made by that
Participant.
8.3. If You assert a patent infringement claim against Participant
alleging that such Participant's Contributor Version directly or
indirectly infringes any patent where such claim is resolved (such as
by license or settlement) prior to the initiation of patent
infringement litigation, then the reasonable value of the licenses
granted by such Participant under Sections 2.1 or 2.2 shall be taken
into account in determining the amount or value of any payment or
license.
8.4. In the event of termination under Sections 8.1 or 8.2 above,
all end user license agreements (excluding distributors and resellers)
which have been validly granted by You or any distributor hereunder
prior to termination shall survive termination.
9. LIMITATION OF LIABILITY.
UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
(INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL
DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE,
OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR
ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY
CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL,
WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF
LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY
RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW
PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE
EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO
THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
10. U.S. GOVERNMENT END USERS.
The Covered Code is a "commercial item," as that term is defined in
48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer
software" and "commercial computer software documentation," as such
terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48
C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995),
all U.S. Government End Users acquire Covered Code with only those
rights set forth herein.
11. MISCELLANEOUS.
This License represents the complete agreement concerning subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. This License shall be governed by
California law provisions (except to the extent applicable law, if
any, provides otherwise), excluding its conflict-of-law provisions.
With respect to disputes in which at least one party is a citizen of,
or an entity chartered or registered to do business in the United
States of America, any litigation relating to this License shall be
subject to the jurisdiction of the Federal Courts of the Northern
District of California, with venue lying in Santa Clara County,
California, with the losing party responsible for costs, including
without limitation, court costs and reasonable attorneys' fees and
expenses. The application of the United Nations Convention on
Contracts for the International Sale of Goods is expressly excluded.
Any law or regulation which provides that the language of a contract
shall be construed against the drafter shall not apply to this
License.
12. RESPONSIBILITY FOR CLAIMS.
As between Initial Developer and the Contributors, each party is
responsible for claims and damages arising, directly or indirectly,
out of its utilization of rights under this License and You agree to
work with Initial Developer and Contributors to distribute such
responsibility on an equitable basis. Nothing herein is intended or
shall be deemed to constitute any admission of liability.
13. MULTIPLE-LICENSED CODE.
Initial Developer may designate portions of the Covered Code as
"Multiple-Licensed". "Multiple-Licensed" means that the Initial
Developer permits you to utilize portions of the Covered Code under
Your choice of the NPL or the alternative licenses, if any, specified
by the Initial Developer in the file described in Exhibit A.
EXHIBIT A -Mozilla Public License.
``The contents of this file are subject to the Mozilla Public License
Version 1.1 (the "License"); you may not use this file except in
compliance with the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
License for the specific language governing rights and limitations
under the License.
The Original Code is ______________________________________.
The Initial Developer of the Original Code is ________________________.
Portions created by ______________________ are Copyright (C) ______
_______________________. All Rights Reserved.
Contributor(s): ______________________________________.
Alternatively, the contents of this file may be used under the terms
of the _____ license (the "[___] License"), in which case the
provisions of [______] License are applicable instead of those
above. If you wish to allow use of your version of this file only
under the terms of the [____] License and not to allow others to use
your version of this file under the MPL, indicate your decision by
deleting the provisions above and replace them with the notice and
other provisions required by the [___] License. If you do not delete
the provisions above, a recipient may use your version of this file
under either the MPL or the [___] License."
[NOTE: The text of this Exhibit A may differ slightly from the text of
the notices in the Source Code files of the Original Code. You should
use the text of this Exhibit A rather than the text found in the
Original Code Source Code for Your Modifications.]
============================================================================
============================================================================
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, 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 or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
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 give any other recipients of the Program a copy of this License
along with the Program.
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 Program or any portion
of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
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 Program, 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 Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) 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; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, 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 executable. However, as a
special exception, the source code 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.
If distribution of executable or 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 counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program 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.
5. 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 Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program 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 to
this License.
7. 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 Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program 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 Program.
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.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program 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.
9. The Free Software Foundation may publish revised and/or new versions
of the 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 Program
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 Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, 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
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. 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 PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.
============================================================================
Additionally, some files (currently the contents of
toolsrc/org/mozilla/javascript/tools/debugger/treetable/) are available
only under the following license:
============================================================================
* Copyright 1997, 1998 Sun Microsystems, Inc. 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 Sun Microsystems 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.
============================================================================

198
mozilla/js/rhino/Makefile Normal file
View File

@@ -0,0 +1,198 @@
#! gmake
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1999 Netscape Communications Corporation. All Rights
# Reserved.
#
# Makefile for javascript in java.
#
# This makefile is intended for packaging releases, and probably isn't
# suitable for production use - it doesn't attempt to do understand
# java dependencies beyond the package level.
#
# The makefiles for the subdirectories included in this package are
# intended to be called by this makefile with the proper CLASSDIR,
# PATH_PREFIX etc. variables. Makefiles in subdirectories are
# actually executed in the toplevel directory, with the PATH_PREFIX
# variable set to the subdirectory where the makefile is located.
#
# Initial version courtesy Mike Ang.
# Next version by Mike McCabe
# Don't include SHELL define (per GNU manual recommendation) because it
# breaks WinNT (with GNU make) builds.
# SHELL = /bin/sh
# Some things we might want to tweek.
CLASSDIR = classes
PACKAGE_NAME = org.mozilla.javascript
PACKAGE_PATH = org/mozilla/javascript
# jar filenames and the directories that build them.
JS_JAR = js.jar
JS_DIR = $(PACKAGE_PATH)
JSTOOLS_JAR = jstools.jar
JSTOOLS_DIR = $(PACKAGE_PATH)/tools
JARS = $(JS_JAR) $(JSTOOLS_JAR)
# It's not polite to store toplevel files in a tarball or zip files.
# What is the name of the toplevel directory to store files in?
# XXX we should probably add versioning to this.
DIST_DIR = jsjava
# XXX test this with sj
JAVAC = javac
# We don't define JFLAGS but we do export it to child
# builds in case it's defined by the environment.
# To build optimized (with javac) say 'make JFLAGS=-O'
GZIP = gzip
ZIP = zip
UNZIP = unzip
# Shouldn't need to change anything below here.
# For Windows NT builds (under GNU make).
ifeq ($(OS_TARGET), WINNT)
CLASSPATHSEP = '\\;'
else
CLASSPATHSEP = :
endif
# Make compatibility - use these instead of gmake 'export VARIABLE'
EXPORTS = CLASSDIR=$(CLASSDIR) JAVAC=$(JAVAC) JFLAGS=$(JFLAGS) SHELL=$(SHELL) \
PACKAGE_PATH=$(PACKAGE_PATH) PACKAGE_NAME=$(PACKAGE_NAME)
helpmessage : FORCE
@echo 'Targets include:'
@echo '\tall - make jars, examples'
@echo '\tjars - make js.jar, jstools.jar'
@echo '\tfast - quick-and-dirty "make jars", for development'
@echo '\texamples - build the .class files in the examples directory'
@echo '\tcheck - perform checks on the source.'
@echo '\tclean - remove intermediate files'
@echo '\tclobber - make clean, and remove .jar files'
@echo '\tzip - make a distribution .zip file'
@echo '\tzip-source - make a distribution .zip file, with source'
@echo '\ttar - make a distribution .tar.gz file'
@echo '\ttar-source - make a distribution .tar.gz, with source'
@echo
@echo 'Define OS_TARGET to "WINNT" to build on Windows NT with GNU make.'
@echo
all : jars examples
jars : $(JARS)
fast : fast_$(JS_JAR) $(JSTOOLS_JAR)
# Always call the sub-Makefile - which may decide that the jar is up to date.
$(JS_JAR) : FORCE
$(MAKE) -f $(JS_DIR)/Makefile JAR=$(@) $(EXPORTS) \
PATH_PREFIX=$(JS_DIR) \
CLASSPATH=.
fast_$(JS_JAR) :
$(MAKE) -f $(JS_DIR)/Makefile JAR=$(JS_JAR) $(EXPORTS) \
PATH_PREFIX=$(JS_DIR) \
CLASSPATH=. \
fast
$(JSTOOLS_JAR) : $(JS_JAR) FORCE
$(MAKE) -f $(JSTOOLS_DIR)/Makefile JAR=$(@) $(EXPORTS) \
PATH_PREFIX=$(JSTOOLS_DIR) \
CLASSPATH=./$(JS_JAR)$(CLASSPATHSEP).
examples : $(JS_JAR) FORCE
$(MAKE) -f examples/Makefile $(EXPORTS) \
PATH_PREFIX=examples \
CLASSPATH=./$(JS_JAR)
# We ask the subdirs to update their MANIFESTs
MANIFEST : FORCE
$(MAKE) -f $(JS_DIR)/Makefile JAR=$(JS_JAR) $(EXPORTS) \
PATH_PREFIX=$(JS_DIR) $(JS_DIR)/MANIFEST
$(MAKE) -f $(JSTOOLS_DIR)/Makefile JAR=$(JSTOOLS_JAR) $(EXPORTS) \
PATH_PREFIX=$(JSTOOLS_DIR) $(JSTOOLS_DIR)/MANIFEST
$(MAKE) -f examples/Makefile $(EXPORTS) \
PATH_PREFIX=examples examples/MANIFEST
# so ls below always has something to work on
touch MANIFEST
# examples/Makefile doesn't get included in the
# MANIFEST file, (which is used to create the non-source distribution) so
# we include it here.
cat examples/MANIFEST $(JS_DIR)/MANIFEST \
$(JSTOOLS_DIR)/MANIFEST \
| xargs ls MANIFEST README.html \
$(JARS) \
Makefile examples/Makefile \
> $(@)
# Make a MANIFEST file containing only the binaries and documentation.
# This could be abstracted further...
MANIFEST_binonly : MANIFEST
cat examples/MANIFEST \
| xargs ls $(JARS) README.html MANIFEST > MANIFEST
# A subroutine - not intended to be called from outside the makefile.
do_zip :
# Make sure we get a fresh one
- rm -r $(DIST_DIR)
- mkdir $(DIST_DIR)
- rm $(DIST_DIR).zip
cat MANIFEST | xargs $(ZIP) -0 -q $(DIST_DIR).zip
mv $(DIST_DIR).zip $(DIST_DIR)
cd $(DIST_DIR) ; \
$(UNZIP) -q $(DIST_DIR).zip ; \
rm $(DIST_DIR).zip
$(ZIP) -r -9 -q $(DIST_DIR).zip $(DIST_DIR)
- rm -r $(DIST_DIR)
zip : check jars examples MANIFEST_binonly do_zip
zip-source : check jars examples MANIFEST do_zip
# A subroutine - not intended to be called from outside the makefile.
do_tar :
- rm -r $(DIST_DIR)
- mkdir $(DIST_DIR)
- rm $(DIST_DIR).tar $(DIST_DIR).tar.gz
cat MANIFEST | xargs tar cf $(DIST_DIR).tar
mv $(DIST_DIR).tar $(DIST_DIR)
cd $(DIST_DIR) ; \
tar xf $(DIST_DIR).tar ; \
rm $(DIST_DIR).tar
tar cf $(DIST_DIR).tar $(DIST_DIR)
- rm -r $(DIST_DIR)
$(GZIP) -9 $(DIST_DIR).tar
tar: check jars examples MANIFEST_binonly do_tar
tar-source : check jars examples MANIFEST do_tar
# These commands just get passed to the respective sub-Makefiles.
clean clobber check:
$(MAKE) -f $(JS_DIR)/Makefile $(EXPORTS) JAR=$(JS_JAR) \
PATH_PREFIX=$(JS_DIR) $(@)
$(MAKE) -f $(JSTOOLS_DIR)/Makefile $(EXPORTS) JAR=$(JSTOOLS_JAR) \
PATH_PREFIX=$(JSTOOLS_DIR) $(@)
$(MAKE) -f examples/Makefile $(EXPORTS) PATH_PREFIX=examples $(@)
#emulate .PHONY
FORCE :

View File

@@ -1,39 +1,4 @@
<html>
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Rhino code, released
- May 6, 1999.
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation.
- Portions created by the Initial Developer are Copyright (C) 1998-1999
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
- Norris Boyd
-
- Alternatively, the contents of this file may be used under the terms of
- the GNU General Public License Version 2 or later (the "GPL"), in which
- case the provisions of the GPL are applicable instead of those above. If
- you wish to allow use of your version of this file only under the terms of
- the GPL and not to allow others to use your version of this file under the
- MPL, indicate your decision by deleting the provisions above and replacing
- them with the notice and other provisions required by the GPL. If you do
- not delete the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- ***** END LICENSE BLOCK ***** -->
<body>
<h1>
<span CLASS=LXRSHORTDESC>
@@ -42,7 +7,7 @@ Rhino: JavaScript in Java<p>
</h1>
<span CLASS=LXRLONGDESC>
Rhino is an implementation of JavaScript in Java. Documentation can be found
<a href="http://www.mozilla.org/rhino/index.html">here</a>.
<a href="http://www.mozilla.org/js/rhino/rhino.html">here</a>.
</span>
</body>
</html>

View File

@@ -1,66 +0,0 @@
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is Rhino code, released May 6, 1999.
#
# The Initial Developer of the Original Code is
# Netscape Communications Corporation.
# Portions created by the Initial Developer are Copyright (C) 1997-1999
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
#
# Alternatively, the contents of this file may be used under the terms of
# the GNU General Public License Version 2 or later (the "GPL"), in which
# case the provisions of the GPL are applicable instead of those above. If
# you wish to allow use of your version of this file only under the terms of
# the GPL and not to allow others to use your version of this file under the
# MPL, indicate your decision by deleting the provisions above and replacing
# them with the notice and other provisions required by the GPL. If you do
# not delete the provisions above, a recipient may use your version of this
# file under either the MPL or the GPL.
#
# ***** END LICENSE BLOCK *****
apiClasses=\
src/org/mozilla/javascript/Callable.java,\
src/org/mozilla/javascript/ClassCache.java,\
src/org/mozilla/javascript/ClassShutter.java,\
src/org/mozilla/javascript/CompilerEnvirons.java,\
src/org/mozilla/javascript/ContinuationPending.java,\
src/org/mozilla/javascript/Context.java,\
src/org/mozilla/javascript/ContextAction.java,\
src/org/mozilla/javascript/ContextFactory.java,\
src/org/mozilla/javascript/GeneratedClassLoader.java,\
src/org/mozilla/javascript/EcmaError.java,\
src/org/mozilla/javascript/ErrorReporter.java,\
src/org/mozilla/javascript/EvaluatorException.java,\
src/org/mozilla/javascript/Function.java,\
src/org/mozilla/javascript/FunctionObject.java,\
src/org/mozilla/javascript/GeneratedClassLoader.java,\
src/org/mozilla/javascript/ImporterTopLevel.java,\
src/org/mozilla/javascript/JavaScriptException.java,\
src/org/mozilla/javascript/RefCallable.java,\
src/org/mozilla/javascript/RhinoException.java,\
src/org/mozilla/javascript/Script.java,\
src/org/mozilla/javascript/Scriptable.java,\
src/org/mozilla/javascript/ScriptableObject.java,\
src/org/mozilla/javascript/SecurityController.java,\
src/org/mozilla/javascript/WrapFactory.java,\
src/org/mozilla/javascript/WrappedException.java,\
src/org/mozilla/javascript/Wrapper.java,\
src/org/mozilla/javascript/Synchronizer.java,\
src/org/mozilla/javascript/optimizer/ClassCompiler.java,\
src/org/mozilla/javascript/debug/DebuggableScript.java,\
src/org/mozilla/javascript/serialize/ScriptableInputStream.java,\
src/org/mozilla/javascript/serialize/ScriptableOutputStream.java

View File

@@ -1 +0,0 @@
This version was built on @datestamp@.

View File

@@ -1,65 +0,0 @@
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is Rhino code, released
# May 6, 1999.
#
# The Initial Developer of the Original Code is
# Netscape Communications Corporation.
# Portions created by the Initial Developer are Copyright (C) 1997-1999
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Igor Bukanov
#
# Alternatively, the contents of this file may be used under the terms of
# the GNU General Public License Version 2 or later (the "GPL"), in which
# case the provisions of the GPL are applicable instead of those above. If
# you wish to allow use of your version of this file only under the terms of
# the GPL and not to allow others to use your version of this file under the
# MPL, indicate your decision by deleting the provisions above and replacing
# them with the notice and other provisions required by the GPL. If you do
# not delete the provisions above, a recipient may use your version of this
# file under either the MPL or the GPL.
#
# ***** END LICENSE BLOCK *****
name: rhino
Name: Rhino
version: 1_7R3pre
# See Context#getImplementationVersion() for format of this!
implementation.version: Rhino 1.7 release 3 PRERELEASE ${implementation.date}
build.dir: build
rhino.jar: js.jar
small-rhino.jar: smalljs.jar
rhino-14.jar: js-14.jar
small-rhino-14.jar: smalljs-14.jar
dist.name: rhino${version}
dist.dir: ${build.dir}/${dist.name}
# compilation destionation
classes: ${build.dir}/classes
# compilation settings
debug: on
target-jvm: 1.5
source-level: 1.5
# jar generation settings
jar-compression: true
# optional external packages
xmlbeans: .
xbean.jar: ${xmlbeans}/lib/xbean.jar
jsr173.jar: ${xmlbeans}/lib/jsr173_1.0_api.jar

View File

@@ -1,343 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Rhino code, released May 6, 1999.
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation.
- Portions created by the Initial Developer are Copyright (C) 1997-1999
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
-
- Alternatively, the contents of this file may be used under the terms of
- the GNU General Public License Version 2 or later (the "GPL"), in which
- case the provisions of the GPL are applicable instead of those above. If
- you wish to allow use of your version of this file only under the terms of
- the GPL and not to allow others to use your version of this file under the
- MPL, indicate your decision by deleting the provisions above and replacing
- them with the notice and other provisions required by the GPL. If you do
- not delete the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- ***** END LICENSE BLOCK ***** -->
<!--
Build file for Rhino using Ant (see http://jakarta.apache.org/ant/index.html)
Requires Ant version 1.2 or later
Compilation currently requires JDK 1.5 or later. Can cross-compile to
support JDK 1.4.
-->
<project name="Rhino" default="help" basedir=".">
<target name="properties">
<!-- Allow user to override default settings from build.properties -->
<property file="build.local.properties" />
<tstamp>
<!-- Specify date part of Context#getImplementationVersion() -->
<format property="implementation.date" pattern="yyyy MM dd"/>
</tstamp>
<property file="build.properties"/>
<property name="dist.file" value="rhino${version}.zip"/>
<property name="dist.source-only-zip" value="rhino${version}-sources.zip"/>
<property file="apiClasses.properties"/>
<property name="xmlimplsrc-build-file"
location="xmlimplsrc/build.xml"/>
<available property="xmlimplsrc-present?"
file="${xmlimplsrc-build-file}" />
</target>
<target name="init" depends="properties">
<mkdir dir="${build.dir}"/>
<mkdir dir="${classes}"/>
<mkdir dir="${dist.dir}"/>
</target>
<target name="compile" depends="init">
<ant antfile="src/build.xml" target="compile"/>
<ant antfile="toolsrc/build.xml" target="compile"/>
<antcall target="xmlimplsrc-compile" />
</target>
<target name="compile-all" depends="compile">
<ant antfile="deprecatedsrc/build.xml" target="compile"/>
</target>
<target name="graph" depends="init">
<ant antfile="src/build.xml" target="graph"/>
</target>
<target name="shell" depends="compile">
<ant antfile="src/build.xml" target="shell"/>
</target>
<target name="copy-source" depends="init">
<ant antfile="src/build.xml" target="copy-source"/>
<ant antfile="toolsrc/build.xml" target="copy-source"/>
<ant antfile="testsrc/build.xml" target="copy-source"/>
<antcall target="xmlimplsrc-copy-source" />
<ant antfile="deprecatedsrc/build.xml" target="copy-source"/>
<copy todir="${dist.dir}" file="build.xml"/>
<copy todir="${dist.dir}" file="build.properties"/>
<copy todir="${dist.dir}" file="apiClasses.properties"/>
<copy todir="${dist.dir}" file="LICENSE.txt"/>
</target>
<target name="xmlimplsrc-compile" if="xmlimplsrc-present?">
<echo>Calling ${xmlimplsrc-build-file}</echo>
<!-- Ignore compilation errors under JDK less then 1.4 -->
<property name="xmlimpl.compile.failonerror" value="no"/>
<ant antfile="${xmlimplsrc-build-file}" target="compile"/>
</target>
<target name="xmlimplsrc-copy-source" if="xmlimplsrc-present?">
<echo>Calling ${xmlimplsrc-build-file}</echo>
<ant antfile="${xmlimplsrc-build-file}" target="copy-source"/>
</target>
<target name="jar" depends="compile-all">
<property name="jarfile" location="${dist.dir}/${rhino.jar}"/>
<jar jarfile="${jarfile}"
basedir="${classes}"
manifest="src/manifest"
compress="${jar-compression}"
/>
</target>
<target name="console" depends="jar">
<property name="jarfile" location="${dist.dir}/${rhino.jar}"/>
<java jar="${jarfile}"
fork="true">
<arg line="-version 170"/>
</java>
</target>
<target name="retrotranslator" depends="retrotranslator-check,retrotranslator-download">
<taskdef name="retrotranslator" classpath="build/download/Retrotranslator-1.2.3-bin/retrotranslator-transformer-1.2.3.jar"
classname="net.sf.retrotranslator.transformer.RetrotranslatorTask"/>
</target>
<target name="retrotranslator-check">
<condition property="retrotranslator.available">
<and>
<available file="build/download/Retrotranslator-1.2.3-bin/retrotranslator-transformer-1.2.3.jar"/>
<available file="build/download/Retrotranslator-1.2.3-bin/retrotranslator-runtime-1.2.3.jar"/>
<available file="build/download/Retrotranslator-1.2.3-bin/backport-util-concurrent-3.1.jar"/>
</and>
</condition>
</target>
<target name="retrotranslator-download" unless="retrotranslator.available">
<mkdir dir="build/download"/>
<get src="http://downloads.sourceforge.net/retrotranslator/Retrotranslator-1.2.3-bin.zip" dest="build/download/Retrotranslator-1.2.3-bin.zip" usetimestamp="true"/>
<unzip src="build/download/Retrotranslator-1.2.3-bin.zip" dest="build/download"/>
</target>
<target name="retrojar" depends="jar,retrotranslator">
<retrotranslator
srcjar="${jarfile}"
destjar="${dist.dir}/${rhino-14.jar}"
embed="org.mozilla.javascript"
/>
</target>
<target name="smalljar" depends="compile">
<property name="smalljarfile" location="${dist.dir}/${small-rhino.jar}"/>
<jar basedir="${classes}" destfile="${smalljarfile}"
compress="${jar-compression}">
<include name="org/mozilla/javascript/*.class"/>
<include name="org/mozilla/javascript/debug/*.class"/>
<include name="org/mozilla/javascript/resources/*.properties"/>
<include name="org/mozilla/javascript/xml/*.class"/>
<include name="org/mozilla/javascript/continuations/*.class"/>
<include name="org/mozilla/javascript/jdk13/*.class"/>
<!-- exclude classes that defines only int constants -->
<exclude name="org/mozilla/javascript/Token.class"/>
<!-- exclude classes that uses class generation library -->
<exclude name="org/mozilla/javascript/JavaAdapter*.class"/>
<include name="org/mozilla/javascript/regexp/*.class"
unless="no-regexp"/>
</jar>
</target>
<target name="retrosmalljar" depends="smalljar,retrotranslator">
<retrotranslator
srcjar="${smalljarfile}"
destjar="${dist.dir}/${small-rhino-14.jar}"
embed="org.mozilla.javascript"
/>
</target>
<target name="copy-examples" depends="init">
<mkdir dir="${dist.dir}/examples"/>
<copy todir="${dist.dir}/examples">
<fileset dir="examples" includes="**/*.java,**/*.js,**/*.html" />
</copy>
</target>
<target name="copy-misc" depends="init">
<filter token="datestamp" value="${TODAY}"/>
<copy todir="${dist.dir}" filtering="yes">
<fileset dir=".">
<patternset>
<include name="build-date"/>
</patternset>
</fileset>
</copy>
</target>
<target name="copy-all" depends="copy-source,copy-examples,copy-misc">
</target>
<target name="javadoc" depends="init">
<mkdir dir="${dist.dir}/javadoc"/>
<javadoc sourcefiles="${apiClasses}"
sourcepath="src"
destdir="${dist.dir}/javadoc"
version="true"
author="true"
windowtitle="${Name}" />
</target>
<target name="dev-javadoc" depends="init">
<mkdir dir="${dist.dir}/javadoc"/>
<javadoc sourcepath="src"
destdir="${dist.dir}/javadoc"
version="true"
package="true"
author="true"
windowtitle="${Name}">
<fileset
dir="."
includes="**/*.java"
excludes="**/deprecatedsrc/**/*.java"
/>
</javadoc>
</target>
<target name="dist" depends="deepclean,jar,retrojar,copy-all,javadoc">
<delete file="${dist.file}" />
<zip destfile="${dist.file}">
<fileset dir="${build.dir}" includes="${dist.name}/**"/>
</zip>
</target>
<target name="source-zip" depends="copy-source,copy-examples,javadoc">
<delete file="${dist.source-only-zip}" />
<zip destfile="${dist.source-only-zip}">
<zipfileset prefix="${dist.name}" dir="${dist.dir}">
<include name="*src/**"/>
<include name="build.xml"/>
<include name="*.properties"/>
<include name="examples/**"/>
</zipfileset>
</zip>
</target>
<target name="compile-debugger">
<ant antfile="toolsrc/build.xml" target="compile-debugger"/>
</target>
<target name="clean" depends="properties">
<delete quiet="true" file="${dist.dir}/${rhino.jar}"/>
<delete quiet="true" file="${dist.dir}/${small-rhino.jar}"/>
<delete quiet="true" dir="${build.dir}"/>
</target>
<target name="deepclean" depends="properties">
<delete quiet="true" dir="${build.dir}"/>
<delete quiet="true" file="${dist.file}"/>
<delete quiet="true" file="${dist.source-only-zip}"/>
</target>
<!--
The next two targets run the JavaScript Test Library tests. Note that these tests are quite extensive and take a long time
to run. They are not documented in the 'help' target for now.
-->
<!--
Run the tests using JUnit. Beware that if you are using Ant from the command-line, there are some difficulties you may
encounter setting this up correctly; see http://ant.apache.org/faq.html#delegating-classloader
IDEs that use Ant as the build system probably handle this fine.
-->
<target name="junit-all" depends="compile">
<ant antfile="testsrc/build.xml" target="junit-coveragereport"/>
</target>
<!--
Run the tests using the Java port of jsdriver.pl. Note that running this port
from the command-line may be more useful running this Ant target, as running
from the command line allows configuration options, such as running with a
non-default optimization level, or running only a subset of the tests.
-->
<target name="jsdriver-run" depends="compile">
<ant antfile="testsrc/build.xml" target="jsdriver" />
</target>
<!--
Compile the JsDriver test driver.
-->
<target name="jsdriver" depends="compile">
<ant antfile="testsrc/build.xml" target="clean" />
<ant antfile="testsrc/build.xml" target="compile" />
</target>
<target name="help" depends="properties">
<echo>The following targets are available with this build file:
clean remove all compiled classes and copied property files
compile compile classes and copy all property files
into ${classes} directory
excluding deprecated code
compile-all compile all classes and copy all property files
into ${classes} directory
including deprecated code
deepclean remove all generated files and directories
dist create ${dist.file} with full Rhino distribution
help print this help
jar create ${rhino.jar} in ${dist.dir}
smalljar create ${small-rhino.jar} in ${dist.dir} with
minimalist set of Rhino classes. See footprint.html
from the doc directory for details.
javadoc generate Rhino API documentation
in ${dist.dir}/javadoc
source-zip create ${dist.source-only-zip} with all Rhino
source files necessary to recreate ${dist.file}
</echo>
</target>
</project>

View File

@@ -1,61 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Rhino code, released May 6, 1999.
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation.
- Portions created by the Initial Developer are Copyright (C) 1997-1999
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
-
- Alternatively, the contents of this file may be used under the terms of
- the GNU General Public License Version 2 or later (the "GPL"), in which
- case the provisions of the GPL are applicable instead of those above. If
- you wish to allow use of your version of this file only under the terms of
- the GPL and not to allow others to use your version of this file under the
- MPL, indicate your decision by deleting the provisions above and replacing
- them with the notice and other provisions required by the GPL. If you do
- not delete the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- ***** END LICENSE BLOCK ***** -->
<project name="src" default="compile" basedir="..">
<property file="build.properties"/>
<target name="compile">
<javac srcdir="deprecatedsrc"
destdir="${classes}"
includes="org/mozilla/javascript/*.java"
deprecation="on"
debug="${debug}"
target="${target-jvm}"
source="${source-level}"
>
</javac>
</target>
<target name="copy-source">
<mkdir dir="${dist.dir}/deprecatedsrc"/>
<copy todir="${dist.dir}/deprecatedsrc">
<fileset dir="deprecatedsrc"
includes="**/*.java,**/*.properties,**/*.xml,manifest"/>
</copy>
</target>
</project>

View File

@@ -1,53 +0,0 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1999.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
// API class
package org.mozilla.javascript;
/**
* @deprecated The exception is no longer thrown by Rhino runtime as
* {@link EvaluatorException} is used instead.
*/
public class ClassDefinitionException extends RuntimeException
{
static final long serialVersionUID = -5637830967241712746L;
public ClassDefinitionException(String detail) {
super(detail);
}
}

View File

@@ -1,52 +0,0 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1999.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Igor Bukanov
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
// API class
package org.mozilla.javascript;
/**
* @deprecated The exception is no longer thrown by Rhino runtime as
* {@link EvaluatorException} is used instead.
*/
public class NotAFunctionException extends RuntimeException
{
static final long serialVersionUID = 6461524852170711724L;
public NotAFunctionException() { }
}

View File

@@ -1,54 +0,0 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1999.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Norris Boyd
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
// API class
package org.mozilla.javascript;
/**
* @deprecated This exception is no longer thrown by Rhino runtime.
*/
public class PropertyException extends RuntimeException
{
static final long serialVersionUID = -8221564865490676219L;
public PropertyException(String detail) {
super(detail);
}
}

View File

@@ -1,367 +0,0 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1999.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-2000
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Ethan Hugg
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
package org.mozilla.javascript.xml.impl.xmlbeans;
import org.apache.xmlbeans.XmlCursor;
import java.util.*;
public class LogicalEquality
{
public static boolean nodesEqual(XmlCursor xmlOne, XmlCursor xmlTwo)
{
boolean result = false;
if (xmlOne.isStartdoc())
{
xmlOne.toFirstContentToken();
}
if (xmlTwo.isStartdoc())
{
xmlTwo.toFirstContentToken();
}
if (xmlOne.currentTokenType() == xmlTwo.currentTokenType())
{
if (xmlOne.isEnddoc())
{
// Both empty
result = true;
}
else if (xmlOne.isAttr())
{
result = attributesEqual(xmlOne, xmlTwo);
}
else if (xmlOne.isText())
{
result = textNodesEqual(xmlOne, xmlTwo);
}
else if (xmlOne.isComment())
{
result = commentsEqual(xmlOne, xmlTwo);
}
else if (xmlOne.isProcinst())
{
result = processingInstructionsEqual(xmlOne, xmlTwo);
}
else if (xmlOne.isStart())
{
// Compare root elements
result = elementsEqual(xmlOne, xmlTwo);
}
}
return result;
}
private static boolean elementsEqual(XmlCursor xmlOne, XmlCursor xmlTwo)
{
boolean result = true;
if (!qnamesEqual(xmlOne.getName(), xmlTwo.getName()))
{
result = false;
}
else
{
// These filter out empty text nodes.
nextToken(xmlOne);
nextToken(xmlTwo);
do
{
if (xmlOne.currentTokenType() != xmlTwo.currentTokenType())
{
// Not same token
result = false;
break;
}
else if (xmlOne.isEnd())
{
// Done with this element, step over end
break;
}
else if (xmlOne.isEnddoc())
{
// Shouldn't get here
break;
}
else if (xmlOne.isAttr())
{
// This one will move us to the first non-attr token.
result = attributeListsEqual(xmlOne, xmlTwo);
}
else
{
if (xmlOne.isText())
{
result = textNodesEqual(xmlOne, xmlTwo);
}
else if (xmlOne.isComment())
{
result = commentsEqual(xmlOne, xmlTwo);
}
else if (xmlOne.isProcinst())
{
result = processingInstructionsEqual(xmlOne, xmlTwo);
}
else if (xmlOne.isStart())
{
result = elementsEqual(xmlOne, xmlTwo);
}
else
{
//XML.log("Unknown token type" + xmlOne.currentTokenType());
}
// These filter out empty text nodes.
nextToken(xmlOne);
nextToken(xmlTwo);
}
}
while(result);
}
return result;
}
/**
*
* @param xmlOne
* @param xmlTwo
* @return
*/
private static boolean attributeListsEqual(XmlCursor xmlOne, XmlCursor xmlTwo)
{
boolean result = true;
TreeMap mapOne = loadAttributeMap(xmlOne);
TreeMap mapTwo = loadAttributeMap(xmlTwo);
if (mapOne.size() != mapTwo.size())
{
result = false;
}
else
{
Set keysOne = mapOne.keySet();
Set keysTwo = mapTwo.keySet();
Iterator itOne = keysOne.iterator();
Iterator itTwo = keysTwo.iterator();
while (result && itOne.hasNext())
{
String valueOne = (String) itOne.next();
String valueTwo = (String) itTwo.next();
if (!valueOne.equals(valueTwo))
{
result = false;
}
else
{
javax.xml.namespace.QName qnameOne = (javax.xml.namespace.QName) mapOne.get(valueOne);
javax.xml.namespace.QName qnameTwo = (javax.xml.namespace.QName) mapTwo.get(valueTwo);
if (!qnamesEqual(qnameOne, qnameTwo))
{
result = false;
}
}
}
}
return result;
}
/**
*
* @param xml
* @return
*/
private static TreeMap loadAttributeMap(XmlCursor xml)
{
TreeMap result = new TreeMap();
while (xml.isAttr())
{
result.put(xml.getTextValue(), xml.getName());
nextToken(xml);
}
return result;
}
/**
*
* @param xmlOne
* @param xmlTwo
* @return
*/
private static boolean attributesEqual(XmlCursor xmlOne, XmlCursor xmlTwo)
{
boolean result = false;
if (xmlOne.isAttr() && xmlTwo.isAttr())
{
if (qnamesEqual(xmlOne.getName(), xmlTwo.getName()))
{
if (xmlOne.getTextValue().equals(xmlTwo.getTextValue()))
{
result = true;
}
}
}
return result;
}
/**
*
* @param xmlOne
* @param xmlTwo
* @return
*/
private static boolean textNodesEqual(XmlCursor xmlOne, XmlCursor xmlTwo)
{
boolean result = false;
if (xmlOne.isText() && xmlTwo.isText())
{
if (xmlOne.getChars().equals(xmlTwo.getChars()))
{
result = true;
}
}
return result;
}
/**
*
* @param xmlOne
* @param xmlTwo
* @return
*/
private static boolean commentsEqual(XmlCursor xmlOne, XmlCursor xmlTwo)
{
boolean result = false;
if (xmlOne.isComment() && xmlTwo.isComment())
{
if (xmlOne.getTextValue().equals(xmlTwo.getTextValue()))
{
result = true;
}
}
return result;
}
/**
*
* @param xmlOne
* @param xmlTwo
* @return
*/
private static boolean processingInstructionsEqual(XmlCursor xmlOne, XmlCursor xmlTwo)
{
boolean result = false;
if (xmlOne.isProcinst() && xmlTwo.isProcinst())
{
if (qnamesEqual(xmlOne.getName(), xmlTwo.getName()))
{
if (xmlOne.getTextValue().equals(xmlTwo.getTextValue()))
{
result = true;
}
}
}
return result;
}
/**
*
* @param qnameOne
* @param qnameTwo
* @return
*/
private static boolean qnamesEqual(javax.xml.namespace.QName qnameOne, javax.xml.namespace.QName qnameTwo)
{
boolean result = false;
if (qnameOne.getNamespaceURI().equals(qnameTwo.getNamespaceURI()))
{
if (qnameOne.getLocalPart().equals(qnameTwo.getLocalPart()))
{
return true;
}
}
return result;
}
/**
* filter out empty textNodes here
*
* @param xml
*/
private static void nextToken(XmlCursor xml)
{
do
{
xml.toNextToken();
if (!xml.isText())
{
// Not a text node
break;
}
else if (xml.getChars().trim().length() > 0)
{
// Text node is not empty
break;
}
}
while (true);
}
}

View File

@@ -1,335 +0,0 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1999.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-2000
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Ethan Hugg
* Terry Lucas
* Milen Nankov
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
package org.mozilla.javascript.xml.impl.xmlbeans;
import org.mozilla.javascript.*;
/**
* Class Namespace
*
*/
class Namespace extends IdScriptableObject
{
static final long serialVersionUID = -5765755238131301744L;
private static final Object NAMESPACE_TAG = "Namespace";
private XMLLibImpl lib;
private String prefix;
private String uri;
public Namespace(XMLLibImpl lib, String uri)
{
super(lib.globalScope(), lib.namespacePrototype);
if (uri == null)
throw new IllegalArgumentException();
this.lib = lib;
this.prefix = (uri.length() == 0) ? "" : null;
this.uri = uri;
}
public Namespace(XMLLibImpl lib, String prefix, String uri)
{
super(lib.globalScope(), lib.namespacePrototype);
if (uri == null)
throw new IllegalArgumentException();
if (uri.length() == 0) {
// prefix should be "" for empty uri
if (prefix == null)
throw new IllegalArgumentException();
if (prefix.length() != 0)
throw new IllegalArgumentException();
}
this.lib = lib;
this.prefix = prefix;
this.uri = uri;
}
public void exportAsJSClass(boolean sealed)
{
exportAsJSClass(MAX_PROTOTYPE_ID, lib.globalScope(), sealed);
}
/**
*
* @return
*/
public String uri()
{
return uri;
}
/**
*
* @return
*/
public String prefix()
{
return prefix;
}
/**
*
* @return
*/
public String toString ()
{
return uri();
}
/**
*
* @return
*/
public String toLocaleString ()
{
return toString();
}
public boolean equals(Object obj)
{
if (!(obj instanceof Namespace)) return false;
return equals((Namespace)obj);
}
protected Object equivalentValues(Object value)
{
if (!(value instanceof Namespace)) return Scriptable.NOT_FOUND;
boolean result = equals((Namespace)value);
return result ? Boolean.TRUE : Boolean.FALSE;
}
private boolean equals(Namespace n)
{
return uri().equals(n.uri());
}
/**
*
* @return
*/
public String getClassName ()
{
return "Namespace";
}
/**
*
* @param hint
* @return
*/
public Object getDefaultValue (Class hint)
{
return uri();
}
// #string_id_map#
private static final int
Id_prefix = 1,
Id_uri = 2,
MAX_INSTANCE_ID = 2;
protected int getMaxInstanceId()
{
return super.getMaxInstanceId() + MAX_INSTANCE_ID;
}
protected int findInstanceIdInfo(String s)
{
int id;
// #generated# Last update: 2004-07-20 19:50:50 CEST
L0: { id = 0; String X = null;
int s_length = s.length();
if (s_length==3) { X="uri";id=Id_uri; }
else if (s_length==6) { X="prefix";id=Id_prefix; }
if (X!=null && X!=s && !X.equals(s)) id = 0;
}
// #/generated#
if (id == 0) return super.findInstanceIdInfo(s);
int attr;
switch (id) {
case Id_prefix:
case Id_uri:
attr = PERMANENT | READONLY;
break;
default: throw new IllegalStateException();
}
return instanceIdInfo(attr, super.getMaxInstanceId() + id);
}
// #/string_id_map#
protected String getInstanceIdName(int id)
{
switch (id - super.getMaxInstanceId()) {
case Id_prefix: return "prefix";
case Id_uri: return "uri";
}
return super.getInstanceIdName(id);
}
protected Object getInstanceIdValue(int id)
{
switch (id - super.getMaxInstanceId()) {
case Id_prefix:
if (prefix == null) return Undefined.instance;
return prefix;
case Id_uri:
return uri;
}
return super.getInstanceIdValue(id);
}
// #string_id_map#
private static final int
Id_constructor = 1,
Id_toString = 2,
Id_toSource = 3,
MAX_PROTOTYPE_ID = 3;
protected int findPrototypeId(String s)
{
int id;
// #generated# Last update: 2004-08-21 12:07:01 CEST
L0: { id = 0; String X = null; int c;
int s_length = s.length();
if (s_length==8) {
c=s.charAt(3);
if (c=='o') { X="toSource";id=Id_toSource; }
else if (c=='t') { X="toString";id=Id_toString; }
}
else if (s_length==11) { X="constructor";id=Id_constructor; }
if (X!=null && X!=s && !X.equals(s)) id = 0;
}
// #/generated#
return id;
}
// #/string_id_map#
protected void initPrototypeId(int id)
{
String s;
int arity;
switch (id) {
case Id_constructor: arity=2; s="constructor"; break;
case Id_toString: arity=0; s="toString"; break;
case Id_toSource: arity=0; s="toSource"; break;
default: throw new IllegalArgumentException(String.valueOf(id));
}
initPrototypeMethod(NAMESPACE_TAG, id, s, arity);
}
public Object execIdCall(IdFunctionObject f,
Context cx,
Scriptable scope,
Scriptable thisObj,
Object[] args)
{
if (!f.hasTag(NAMESPACE_TAG)) {
return super.execIdCall(f, cx, scope, thisObj, args);
}
int id = f.methodId();
switch (id) {
case Id_constructor:
return jsConstructor(cx, (thisObj == null), args);
case Id_toString:
return realThis(thisObj, f).toString();
case Id_toSource:
return realThis(thisObj, f).js_toSource();
}
throw new IllegalArgumentException(String.valueOf(id));
}
private Namespace realThis(Scriptable thisObj, IdFunctionObject f)
{
if(!(thisObj instanceof Namespace))
throw incompatibleCallError(f);
return (Namespace)thisObj;
}
private Object jsConstructor(Context cx, boolean inNewExpr, Object[] args)
{
if (!inNewExpr && args.length == 1) {
return lib.castToNamespace(cx, args[0]);
}
if (args.length == 0) {
return lib.constructNamespace(cx);
} else if (args.length == 1) {
return lib.constructNamespace(cx, args[0]);
} else {
return lib.constructNamespace(cx, args[0], args[1]);
}
}
private String js_toSource()
{
StringBuffer sb = new StringBuffer();
sb.append('(');
toSourceImpl(prefix, uri, sb);
sb.append(')');
return sb.toString();
}
static void toSourceImpl(String prefix, String uri, StringBuffer sb)
{
sb.append("new Namespace(");
if (uri.length() == 0) {
if (!"".equals(prefix)) throw new IllegalArgumentException(prefix);
} else {
sb.append('\'');
if (prefix != null) {
sb.append(ScriptRuntime.escapeString(prefix, '\''));
sb.append("', '");
}
sb.append(ScriptRuntime.escapeString(uri, '\''));
sb.append('\'');
}
sb.append(')');
}
}

View File

@@ -1,350 +0,0 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1999.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-2000
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Milen Nankov
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
package org.mozilla.javascript.xml.impl.xmlbeans;
import java.util.*;
import org.apache.xmlbeans.XmlCursor;
import org.mozilla.javascript.*;
class NamespaceHelper
{
private XMLLibImpl lib;
private final Map prefixToURI = new HashMap();
private final Map uriToPrefix = new HashMap();
// A set of URIs that are used without explicit namespace declaration in scope.
private final Set undeclared = new HashSet();
private NamespaceHelper(XMLLibImpl lib)
{
this.lib = lib;
// Insert the default namespace
prefixToURI.put("", "");
Set prefixes = new HashSet();
prefixes.add("");
uriToPrefix.put("", prefixes);
}
/**
* Declared a new namespace
*
* @param prefix
* @param uri
* @param declarations
*/
private void declareNamespace(String prefix, String uri, ObjArray declarations)
{
Set prefixes = (Set)uriToPrefix.get(uri);
if(prefixes == null)
{
prefixes = new HashSet();
uriToPrefix.put(uri, prefixes);
}
if(!prefixes.contains(prefix))
{
String oldURI = (String)prefixToURI.get(prefix);
// Add the new mapping
prefixes.add(prefix);
prefixToURI.put(prefix, uri);
if(declarations != null)
declarations.add(new Namespace(lib, prefix, uri));
if(oldURI != null)
{
// Update the existing mapping
prefixes = (Set)uriToPrefix.get(oldURI);
prefixes.remove(prefix);
}
}
}
/**
* Updates the internal state of this NamespaceHelper to reflect the
* existance of the XML token pointed to by the cursor.
*/
private void processName(XmlCursor cursor, ObjArray declarations)
{
javax.xml.namespace.QName qname = cursor.getName();
String uri = qname.getNamespaceURI();
Set prefixes = (Set)uriToPrefix.get(uri);
if(prefixes == null || prefixes.size() == 0)
{
undeclared.add(uri);
if(declarations != null)
declarations.add(new Namespace(lib, uri));
}
}
/**
* Updates the internal state of this NamespaceHelper with the
* namespace information of the element pointed to by the cursor.
*/
private void update(XmlCursor cursor, ObjArray declarations)
{
// Process the Namespace declarations
cursor.push();
while(cursor.toNextToken().isAnyAttr())
{
if(cursor.isNamespace())
{
javax.xml.namespace.QName name = cursor.getName();
String prefix = name.getLocalPart();
String uri = name.getNamespaceURI();
declareNamespace(prefix, uri, declarations);
}
}
cursor.pop();
// Process the element
processName(cursor, declarations);
// Process the attributes
cursor.push();
boolean hasNext = cursor.toFirstAttribute();
while(hasNext)
{
processName(cursor, declarations);
hasNext = cursor.toNextAttribute();
}
cursor.pop();
}
/**
* @return Object[] array of Namespace objects in scope at the cursor.
*/
public static Object[] inScopeNamespaces(XMLLibImpl lib, XmlCursor cursor)
{
ObjArray namespaces = new ObjArray();
NamespaceHelper helper = new NamespaceHelper(lib);
cursor.push();
int depth = 0;
while(cursor.hasPrevToken())
{
if(cursor.isContainer())
{
cursor.push();
depth++;
}
cursor.toParent();
}
for(int i = 0; i < depth; i++)
{
cursor.pop();
helper.update(cursor, null);
}
Iterator i = helper.prefixToURI.entrySet().iterator();
while(i.hasNext())
{
Map.Entry entry = (Map.Entry)i.next();
Namespace ns = new Namespace(lib, (String)entry.getKey(),
(String)entry.getValue());
namespaces.add(ns);
}
i = helper.undeclared.iterator();
while(i.hasNext())
{
Namespace ns = new Namespace(lib, (String)i.next());
namespaces.add(ns);
}
cursor.pop();
return namespaces.toArray();
}
static Namespace getNamespace(XMLLibImpl lib, XmlCursor cursor,
Object[] inScopeNamespaces)
{
String uri;
String prefix;
if (cursor.isProcinst()) {
uri = "";
prefix = "";
} else {
javax.xml.namespace.QName qname = cursor.getName();
uri = qname.getNamespaceURI();
prefix = qname.getPrefix();
}
if (inScopeNamespaces == null)
return new Namespace(lib, prefix, uri);
Namespace result = null;
for (int i = 0; i != inScopeNamespaces.length; ++i) {
Namespace ns = (Namespace)inScopeNamespaces[i];
if(ns == null) continue;
String nsURI = ns.uri();
if(nsURI.equals(uri))
{
if(prefix.equals(ns.prefix()))
{
result = ns;
break;
}
if(result == null ||
(result.prefix() == null &&
ns.prefix() != null))
result = ns;
}
}
if(result == null)
result = new Namespace(lib, prefix, uri);
return result;
}
/**
* @return List of Namespace objects that are declared in the container pointed to by the cursor.
*/
public static Object[] namespaceDeclarations(XMLLibImpl lib, XmlCursor cursor)
{
ObjArray declarations = new ObjArray();
NamespaceHelper helper = new NamespaceHelper(lib);
cursor.push();
int depth = 0;
while(cursor.hasPrevToken())
{
if(cursor.isContainer())
{
cursor.push();
depth++;
}
cursor.toParent();
}
for(int i = 0; i < depth - 1; i++)
{
cursor.pop();
helper.update(cursor, null);
}
if(depth > 0)
{
cursor.pop();
helper.update(cursor, declarations);
}
cursor.pop();
return declarations.toArray();
}
/**
* @return Prefix to URI map of all namespaces in scope at the cursor.
*/
public static Map getAllNamespaces(XMLLibImpl lib, XmlCursor cursor)
{
NamespaceHelper helper = new NamespaceHelper(lib);
cursor.push();
int depth = 0;
while(cursor.hasPrevToken())
{
if(cursor.isContainer())
{
cursor.push();
depth++;
}
cursor.toParent();
}
for(int i = 0; i < depth; i++)
{
cursor.pop();
helper.update(cursor, null);
}
cursor.pop();
return helper.prefixToURI;
}
public static void getNamespaces(XmlCursor cursor, Map prefixToURI)
{
cursor.push();
while(cursor.toNextToken().isAnyAttr())
{
if(cursor.isNamespace())
{
javax.xml.namespace.QName name = cursor.getName();
String prefix = name.getLocalPart();
String uri = name.getNamespaceURI();
prefixToURI.put(prefix, uri);
}
}
cursor.pop();
}
public static void removeNamespace(XmlCursor cursor, String prefix)
{
cursor.push();
while(cursor.toNextToken().isAnyAttr())
{
if(cursor.isNamespace())
{
javax.xml.namespace.QName name = cursor.getName();
if(name.getLocalPart().equals(prefix))
{
cursor.removeXml();
break;
}
}
}
cursor.pop();
}
}

View File

@@ -1,321 +0,0 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1999.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-2000
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Ethan Hugg
* Terry Lucas
* Milen Nankov
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
package org.mozilla.javascript.xml.impl.xmlbeans;
import org.mozilla.javascript.*;
/**
* Class QName
*
*/
final class QName extends IdScriptableObject
{
static final long serialVersionUID = 416745167693026750L;
private static final Object QNAME_TAG = "QName";
XMLLibImpl lib;
private String prefix;
private String localName;
private String uri;
QName(XMLLibImpl lib, String uri, String localName, String prefix)
{
super(lib.globalScope(), lib.qnamePrototype);
if (localName == null) throw new IllegalArgumentException();
this.lib = lib;
this.uri = uri;
this.prefix = prefix;
this.localName = localName;
}
void exportAsJSClass(boolean sealed)
{
exportAsJSClass(MAX_PROTOTYPE_ID, lib.globalScope(), sealed);
}
/**
*
* @return
*/
public String toString()
{
String result;
if (uri == null)
{
result = "*::".concat(localName);
}
else if(uri.length() == 0)
{
result = localName;
}
else
{
result = uri + "::" + localName;
}
return result;
}
public String localName()
{
return localName;
}
String prefix()
{
return (prefix == null) ? prefix : "";
}
String uri()
{
return uri;
}
public boolean equals(Object obj)
{
if(!(obj instanceof QName)) return false;
return equals((QName)obj);
}
protected Object equivalentValues(Object value)
{
if(!(value instanceof QName)) return Scriptable.NOT_FOUND;
boolean result = equals((QName)value);
return result ? Boolean.TRUE : Boolean.FALSE;
}
private boolean equals(QName q)
{
boolean result;
if (uri == null) {
result = q.uri == null && localName.equals(q.localName);
} else {
result = uri.equals(q.uri) && localName.equals(q.localName);
}
return result;
}
/**
*
* @return
*/
public String getClassName ()
{
return "QName";
}
/**
*
* @param hint
* @return
*/
public Object getDefaultValue (Class hint)
{
return toString();
}
// #string_id_map#
private static final int
Id_localName = 1,
Id_uri = 2,
MAX_INSTANCE_ID = 2;
protected int getMaxInstanceId()
{
return super.getMaxInstanceId() + MAX_INSTANCE_ID;
}
protected int findInstanceIdInfo(String s)
{
int id;
// #generated# Last update: 2004-07-18 12:32:51 CEST
L0: { id = 0; String X = null;
int s_length = s.length();
if (s_length==3) { X="uri";id=Id_uri; }
else if (s_length==9) { X="localName";id=Id_localName; }
if (X!=null && X!=s && !X.equals(s)) id = 0;
}
// #/generated#
if (id == 0) return super.findInstanceIdInfo(s);
int attr;
switch (id) {
case Id_localName:
case Id_uri:
attr = PERMANENT | READONLY;
break;
default: throw new IllegalStateException();
}
return instanceIdInfo(attr, super.getMaxInstanceId() + id);
}
// #/string_id_map#
protected String getInstanceIdName(int id)
{
switch (id - super.getMaxInstanceId()) {
case Id_localName: return "localName";
case Id_uri: return "uri";
}
return super.getInstanceIdName(id);
}
protected Object getInstanceIdValue(int id)
{
switch (id - super.getMaxInstanceId()) {
case Id_localName: return localName;
case Id_uri: return uri;
}
return super.getInstanceIdValue(id);
}
// #string_id_map#
private static final int
Id_constructor = 1,
Id_toString = 2,
Id_toSource = 3,
MAX_PROTOTYPE_ID = 3;
protected int findPrototypeId(String s)
{
int id;
// #generated# Last update: 2004-08-21 12:45:13 CEST
L0: { id = 0; String X = null; int c;
int s_length = s.length();
if (s_length==8) {
c=s.charAt(3);
if (c=='o') { X="toSource";id=Id_toSource; }
else if (c=='t') { X="toString";id=Id_toString; }
}
else if (s_length==11) { X="constructor";id=Id_constructor; }
if (X!=null && X!=s && !X.equals(s)) id = 0;
}
// #/generated#
return id;
}
// #/string_id_map#
protected void initPrototypeId(int id)
{
String s;
int arity;
switch (id) {
case Id_constructor: arity=2; s="constructor"; break;
case Id_toString: arity=0; s="toString"; break;
case Id_toSource: arity=0; s="toSource"; break;
default: throw new IllegalArgumentException(String.valueOf(id));
}
initPrototypeMethod(QNAME_TAG, id, s, arity);
}
public Object execIdCall(IdFunctionObject f,
Context cx,
Scriptable scope,
Scriptable thisObj,
Object[] args)
{
if (!f.hasTag(QNAME_TAG)) {
return super.execIdCall(f, cx, scope, thisObj, args);
}
int id = f.methodId();
switch (id) {
case Id_constructor:
return jsConstructor(cx, (thisObj == null), args);
case Id_toString:
return realThis(thisObj, f).toString();
case Id_toSource:
return realThis(thisObj, f).js_toSource();
}
throw new IllegalArgumentException(String.valueOf(id));
}
private QName realThis(Scriptable thisObj, IdFunctionObject f)
{
if(!(thisObj instanceof QName))
throw incompatibleCallError(f);
return (QName)thisObj;
}
private Object jsConstructor(Context cx, boolean inNewExpr, Object[] args)
{
if (!inNewExpr && args.length == 1) {
return lib.castToQName(cx, args[0]);
}
if (args.length == 0) {
return lib.constructQName(cx, Undefined.instance);
} else if (args.length == 1) {
return lib.constructQName(cx, args[0]);
} else {
return lib.constructQName(cx, args[0], args[1]);
}
}
private String js_toSource()
{
StringBuffer sb = new StringBuffer();
sb.append('(');
toSourceImpl(uri, localName, prefix, sb);
sb.append(')');
return sb.toString();
}
private static void toSourceImpl(String uri, String localName,
String prefix, StringBuffer sb)
{
sb.append("new QName(");
if (uri == null && prefix == null) {
if (!"*".equals(localName)) {
sb.append("null, ");
}
} else {
Namespace.toSourceImpl(prefix, uri, sb);
sb.append(", ");
}
sb.append('\'');
sb.append(ScriptRuntime.escapeString(localName, '\''));
sb.append("')");
}
}

View File

@@ -1,269 +0,0 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1999.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-2000
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Igor Bukanov
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
package org.mozilla.javascript.xml.impl.xmlbeans;
import org.mozilla.javascript.*;
class XMLCtor extends IdFunctionObject
{
static final long serialVersionUID = -8708195078359817341L;
private static final Object XMLCTOR_TAG = "XMLCtor";
private XMLLibImpl lib;
XMLCtor(XML xml, Object tag, int id, int arity)
{
super(xml, tag, id, arity);
this.lib = xml.lib;
activatePrototypeMap(MAX_FUNCTION_ID);
}
private void writeSetting(Scriptable target)
{
for (int i = 1; i <= MAX_INSTANCE_ID; ++i) {
int id = super.getMaxInstanceId() + i;
String name = getInstanceIdName(id);
Object value = getInstanceIdValue(id);
ScriptableObject.putProperty(target, name, value);
}
}
private void readSettings(Scriptable source)
{
for (int i = 1; i <= MAX_INSTANCE_ID; ++i) {
int id = super.getMaxInstanceId() + i;
String name = getInstanceIdName(id);
Object value = ScriptableObject.getProperty(source, name);
if (value == Scriptable.NOT_FOUND) {
continue;
}
switch (i) {
case Id_ignoreComments:
case Id_ignoreProcessingInstructions:
case Id_ignoreWhitespace:
case Id_prettyPrinting:
if (!(value instanceof Boolean)) {
continue;
}
break;
case Id_prettyIndent:
if (!(value instanceof Number)) {
continue;
}
break;
default:
throw new IllegalStateException();
}
setInstanceIdValue(id, value);
}
}
// #string_id_map#
private static final int
Id_ignoreComments = 1,
Id_ignoreProcessingInstructions = 2,
Id_ignoreWhitespace = 3,
Id_prettyIndent = 4,
Id_prettyPrinting = 5,
MAX_INSTANCE_ID = 5;
protected int getMaxInstanceId()
{
return super.getMaxInstanceId() + MAX_INSTANCE_ID;
}
protected int findInstanceIdInfo(String s) {
int id;
// #generated# Last update: 2004-07-19 13:03:52 CEST
L0: { id = 0; String X = null; int c;
L: switch (s.length()) {
case 12: X="prettyIndent";id=Id_prettyIndent; break L;
case 14: c=s.charAt(0);
if (c=='i') { X="ignoreComments";id=Id_ignoreComments; }
else if (c=='p') { X="prettyPrinting";id=Id_prettyPrinting; }
break L;
case 16: X="ignoreWhitespace";id=Id_ignoreWhitespace; break L;
case 28: X="ignoreProcessingInstructions";id=Id_ignoreProcessingInstructions; break L;
}
if (X!=null && X!=s && !X.equals(s)) id = 0;
}
// #/generated#
if (id == 0) return super.findInstanceIdInfo(s);
int attr;
switch (id) {
case Id_ignoreComments:
case Id_ignoreProcessingInstructions:
case Id_ignoreWhitespace:
case Id_prettyIndent:
case Id_prettyPrinting:
attr = PERMANENT | DONTENUM;
break;
default: throw new IllegalStateException();
}
return instanceIdInfo(attr, super.getMaxInstanceId() + id);
}
// #/string_id_map#
protected String getInstanceIdName(int id)
{
switch (id - super.getMaxInstanceId()) {
case Id_ignoreComments: return "ignoreComments";
case Id_ignoreProcessingInstructions: return "ignoreProcessingInstructions";
case Id_ignoreWhitespace: return "ignoreWhitespace";
case Id_prettyIndent: return "prettyIndent";
case Id_prettyPrinting: return "prettyPrinting";
}
return super.getInstanceIdName(id);
}
protected Object getInstanceIdValue(int id)
{
switch (id - super.getMaxInstanceId()) {
case Id_ignoreComments:
return ScriptRuntime.wrapBoolean(lib.ignoreComments);
case Id_ignoreProcessingInstructions:
return ScriptRuntime.wrapBoolean(lib.ignoreProcessingInstructions);
case Id_ignoreWhitespace:
return ScriptRuntime.wrapBoolean(lib.ignoreWhitespace);
case Id_prettyIndent:
return ScriptRuntime.wrapInt(lib.prettyIndent);
case Id_prettyPrinting:
return ScriptRuntime.wrapBoolean(lib.prettyPrinting);
}
return super.getInstanceIdValue(id);
}
protected void setInstanceIdValue(int id, Object value)
{
switch (id - super.getMaxInstanceId()) {
case Id_ignoreComments:
lib.ignoreComments = ScriptRuntime.toBoolean(value);
return;
case Id_ignoreProcessingInstructions:
lib.ignoreProcessingInstructions = ScriptRuntime.toBoolean(value);
return;
case Id_ignoreWhitespace:
lib.ignoreWhitespace = ScriptRuntime.toBoolean(value);
return;
case Id_prettyIndent:
lib.prettyIndent = ScriptRuntime.toInt32(value);
return;
case Id_prettyPrinting:
lib.prettyPrinting = ScriptRuntime.toBoolean(value);
return;
}
super.setInstanceIdValue(id, value);
}
// #string_id_map#
private static final int
Id_defaultSettings = 1,
Id_settings = 2,
Id_setSettings = 3,
MAX_FUNCTION_ID = 3;
protected int findPrototypeId(String s)
{
int id;
// #generated# Last update: 2004-07-19 13:03:52 CEST
L0: { id = 0; String X = null;
int s_length = s.length();
if (s_length==8) { X="settings";id=Id_settings; }
else if (s_length==11) { X="setSettings";id=Id_setSettings; }
else if (s_length==15) { X="defaultSettings";id=Id_defaultSettings; }
if (X!=null && X!=s && !X.equals(s)) id = 0;
}
// #/generated#
return id;
}
// #/string_id_map#
protected void initPrototypeId(int id)
{
String s;
int arity;
switch (id) {
case Id_defaultSettings: arity=0; s="defaultSettings"; break;
case Id_settings: arity=0; s="settings"; break;
case Id_setSettings: arity=1; s="setSettings"; break;
default: throw new IllegalArgumentException(String.valueOf(id));
}
initPrototypeMethod(XMLCTOR_TAG, id, s, arity);
}
public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
Scriptable thisObj, Object[] args)
{
if (!f.hasTag(XMLCTOR_TAG)) {
return super.execIdCall(f, cx, scope, thisObj, args);
}
int id = f.methodId();
switch (id) {
case Id_defaultSettings: {
lib.defaultSettings();
Scriptable obj = cx.newObject(scope);
writeSetting(obj);
return obj;
}
case Id_settings: {
Scriptable obj = cx.newObject(scope);
writeSetting(obj);
return obj;
}
case Id_setSettings: {
if (args.length == 0
|| args[0] == null
|| args[0] == Undefined.instance)
{
lib.defaultSettings();
} else if (args[0] instanceof Scriptable) {
readSettings((Scriptable)args[0]);
}
return Undefined.instance;
}
}
throw new IllegalArgumentException(String.valueOf(id));
}
}

View File

@@ -1,754 +0,0 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1999.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-2000
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Igor Bukanov
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
package org.mozilla.javascript.xml.impl.xmlbeans;
import java.io.Serializable;
import org.mozilla.javascript.*;
import org.mozilla.javascript.xml.*;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlObject;
public final class XMLLibImpl extends XMLLib implements Serializable
{
private static final long serialVersionUID = 1L;
private Scriptable globalScope;
XML xmlPrototype;
XMLList xmlListPrototype;
Namespace namespacePrototype;
QName qnamePrototype;
// Environment settings...
boolean ignoreComments;
boolean ignoreProcessingInstructions;
boolean ignoreWhitespace;
boolean prettyPrinting;
int prettyIndent;
Scriptable globalScope()
{
return globalScope;
}
private XMLLibImpl(Scriptable globalScope)
{
this.globalScope = globalScope;
defaultSettings();
}
public static void init(Context cx, Scriptable scope, boolean sealed)
{
// To force LinkageError if XmlObject is not available
XmlObject.class.getName();
XMLLibImpl lib = new XMLLibImpl(scope);
XMLLib bound = lib.bindToScope(scope);
if (bound == lib) {
lib.exportToScope(sealed);
}
}
private void exportToScope(boolean sealed)
{
xmlPrototype = XML.createEmptyXML(this);
xmlListPrototype = new XMLList(this);
namespacePrototype = new Namespace(this, "", "");
qnamePrototype = new QName(this, "", "", "");
xmlPrototype.exportAsJSClass(sealed);
xmlListPrototype.exportAsJSClass(sealed);
namespacePrototype.exportAsJSClass(sealed);
qnamePrototype.exportAsJSClass(sealed);
}
void defaultSettings()
{
ignoreComments = true;
ignoreProcessingInstructions = true;
ignoreWhitespace = true;
prettyPrinting = true;
prettyIndent = 2;
}
XMLName toAttributeName(Context cx, Object nameValue)
{
String uri;
String localName;
if (nameValue instanceof String) {
uri = "";
localName = (String)nameValue;
} else if (nameValue instanceof XMLName) {
XMLName xmlName = (XMLName)nameValue;
if (!xmlName.isAttributeName()) {
xmlName.setAttributeName();
}
return xmlName;
} else if (nameValue instanceof QName) {
QName qname = (QName)nameValue;
uri = qname.uri();
localName = qname.localName();
} else if (nameValue instanceof Boolean
|| nameValue instanceof Number
|| nameValue == Undefined.instance
|| nameValue == null)
{
throw badXMLName(nameValue);
} else {
uri = "";
localName = ScriptRuntime.toString(nameValue);
}
XMLName xmlName = XMLName.formProperty(uri, localName);
xmlName.setAttributeName();
return xmlName;
}
private static RuntimeException badXMLName(Object value)
{
String msg;
if (value instanceof Number) {
msg = "Can not construct XML name from number: ";
} else if (value instanceof Boolean) {
msg = "Can not construct XML name from boolean: ";
} else if (value == Undefined.instance || value == null) {
msg = "Can not construct XML name from ";
} else {
throw new IllegalArgumentException(value.toString());
}
return ScriptRuntime.typeError(msg+ScriptRuntime.toString(value));
}
XMLName toXMLName(Context cx, Object nameValue)
{
XMLName result;
if (nameValue instanceof XMLName) {
result = (XMLName)nameValue;
} else if (nameValue instanceof QName) {
QName qname = (QName)nameValue;
result = XMLName.formProperty(qname.uri(), qname.localName());
} else if (nameValue instanceof String) {
result = toXMLNameFromString(cx, (String)nameValue);
} else if (nameValue instanceof Boolean
|| nameValue instanceof Number
|| nameValue == Undefined.instance
|| nameValue == null)
{
throw badXMLName(nameValue);
} else {
String name = ScriptRuntime.toString(nameValue);
result = toXMLNameFromString(cx, name);
}
return result;
}
/**
* If value represents Uint32 index, make it available through
* ScriptRuntime.lastUint32Result(cx) and return null.
* Otherwise return the same value as toXMLName(cx, value).
*/
XMLName toXMLNameOrIndex(Context cx, Object value)
{
XMLName result;
if (value instanceof XMLName) {
result = (XMLName)value;
} else if (value instanceof String) {
String str = (String)value;
long test = ScriptRuntime.testUint32String(str);
if (test >= 0) {
ScriptRuntime.storeUint32Result(cx, test);
result = null;
} else {
result = toXMLNameFromString(cx, str);
}
} else if (value instanceof Number) {
double d = ((Number)value).doubleValue();
long l = (long)d;
if (l == d && 0 <= l && l <= 0xFFFFFFFFL) {
ScriptRuntime.storeUint32Result(cx, l);
result = null;
} else {
throw badXMLName(value);
}
} else if (value instanceof QName) {
QName qname = (QName)value;
String uri = qname.uri();
boolean number = false;
result = null;
if (uri != null && uri.length() == 0) {
// Only in this case qname.toString() can resemble uint32
long test = ScriptRuntime.testUint32String(uri);
if (test >= 0) {
ScriptRuntime.storeUint32Result(cx, test);
number = true;
}
}
if (!number) {
result = XMLName.formProperty(uri, qname.localName());
}
} else if (value instanceof Boolean
|| value == Undefined.instance
|| value == null)
{
throw badXMLName(value);
} else {
String str = ScriptRuntime.toString(value);
long test = ScriptRuntime.testUint32String(str);
if (test >= 0) {
ScriptRuntime.storeUint32Result(cx, test);
result = null;
} else {
result = toXMLNameFromString(cx, str);
}
}
return result;
}
XMLName toXMLNameFromString(Context cx, String name)
{
if (name == null)
throw new IllegalArgumentException();
int l = name.length();
if (l != 0) {
char firstChar = name.charAt(0);
if (firstChar == '*') {
if (l == 1) {
return XMLName.formStar();
}
} else if (firstChar == '@') {
XMLName xmlName = XMLName.formProperty("", name.substring(1));
xmlName.setAttributeName();
return xmlName;
}
}
String uri = getDefaultNamespaceURI(cx);
return XMLName.formProperty(uri, name);
}
Namespace constructNamespace(Context cx, Object uriValue)
{
String prefix;
String uri;
if (uriValue instanceof Namespace) {
Namespace ns = (Namespace)uriValue;
prefix = ns.prefix();
uri = ns.uri();
} else if (uriValue instanceof QName) {
QName qname = (QName)uriValue;
uri = qname.uri();
if (uri != null) {
prefix = qname.prefix();
} else {
uri = qname.toString();
prefix = null;
}
} else {
uri = ScriptRuntime.toString(uriValue);
prefix = (uri.length() == 0) ? "" : null;
}
return new Namespace(this, prefix, uri);
}
Namespace castToNamespace(Context cx, Object namescapeObj)
{
if (namescapeObj instanceof Namespace) {
return (Namespace)namescapeObj;
}
return constructNamespace(cx, namescapeObj);
}
Namespace constructNamespace(Context cx)
{
return new Namespace(this, "", "");
}
public Namespace constructNamespace(Context cx, Object prefixValue,
Object uriValue)
{
String prefix;
String uri;
if (uriValue instanceof QName) {
QName qname = (QName)uriValue;
uri = qname.uri();
if (uri == null) {
uri = qname.toString();
}
} else {
uri = ScriptRuntime.toString(uriValue);
}
if (uri.length() == 0) {
if (prefixValue == Undefined.instance) {
prefix = "";
} else {
prefix = ScriptRuntime.toString(prefixValue);
if (prefix.length() != 0) {
throw ScriptRuntime.typeError(
"Illegal prefix '"+prefix+"' for 'no namespace'.");
}
}
} else if (prefixValue == Undefined.instance) {
prefix = "";
} else if (!isXMLName(cx, prefixValue)) {
prefix = "";
} else {
prefix = ScriptRuntime.toString(prefixValue);
}
return new Namespace(this, prefix, uri);
}
String getDefaultNamespaceURI(Context cx)
{
String uri = "";
if (cx == null) {
cx = Context.getCurrentContext();
}
if (cx != null) {
Object ns = ScriptRuntime.searchDefaultNamespace(cx);
if (ns != null) {
if (ns instanceof Namespace) {
uri = ((Namespace)ns).uri();
} else {
// Should not happen but for now it could
// due to bad searchDefaultNamespace implementation.
}
}
}
return uri;
}
Namespace getDefaultNamespace(Context cx)
{
if (cx == null) {
cx = Context.getCurrentContext();
if (cx == null) {
return namespacePrototype;
}
}
Namespace result;
Object ns = ScriptRuntime.searchDefaultNamespace(cx);
if (ns == null) {
result = namespacePrototype;
} else {
if (ns instanceof Namespace) {
result = (Namespace)ns;
} else {
// Should not happen but for now it could
// due to bad searchDefaultNamespace implementation.
result = namespacePrototype;
}
}
return result;
}
QName castToQName(Context cx, Object qnameValue)
{
if (qnameValue instanceof QName) {
return (QName)qnameValue;
}
return constructQName(cx, qnameValue);
}
QName constructQName(Context cx, Object nameValue)
{
QName result;
if (nameValue instanceof QName) {
QName qname = (QName)nameValue;
result = new QName(this, qname.uri(), qname.localName(),
qname.prefix());
} else {
String localName = ScriptRuntime.toString(nameValue);
result = constructQNameFromString(cx, localName);
}
return result;
}
/**
* Optimized version of constructQName for String type
*/
QName constructQNameFromString(Context cx, String localName)
{
if (localName == null)
throw new IllegalArgumentException();
String uri;
String prefix;
if ("*".equals(localName)) {
uri = null;
prefix = null;
} else {
Namespace ns = getDefaultNamespace(cx);
uri = ns.uri();
prefix = ns.prefix();
}
return new QName(this, uri, localName, prefix);
}
QName constructQName(Context cx, Object namespaceValue, Object nameValue)
{
String uri;
String localName;
String prefix;
if (nameValue instanceof QName) {
QName qname = (QName)nameValue;
localName = qname.localName();
} else {
localName = ScriptRuntime.toString(nameValue);
}
Namespace ns;
if (namespaceValue == Undefined.instance) {
if ("*".equals(localName)) {
ns = null;
} else {
ns = getDefaultNamespace(cx);
}
} else if (namespaceValue == null) {
ns = null;
} else if (namespaceValue instanceof Namespace) {
ns = (Namespace)namespaceValue;
} else {
ns = constructNamespace(cx, namespaceValue);
}
if (ns == null) {
uri = null;
prefix = null;
} else {
uri = ns.uri();
prefix = ns.prefix();
}
return new QName(this, uri, localName, prefix);
}
Object addXMLObjects(Context cx, XMLObject obj1, XMLObject obj2)
{
XMLList listToAdd = new XMLList(this);
if (obj1 instanceof XMLList) {
XMLList list1 = (XMLList)obj1;
if (list1.length() == 1) {
listToAdd.addToList(list1.item(0));
} else {
// Might be xmlFragment + xmlFragment + xmlFragment + ...;
// then the result will be an XMLList which we want to be an
// rValue and allow it to be assigned to an lvalue.
listToAdd = new XMLList(this, obj1);
}
} else {
listToAdd.addToList(obj1);
}
if (obj2 instanceof XMLList) {
XMLList list2 = (XMLList)obj2;
for (int i = 0; i < list2.length(); i++) {
listToAdd.addToList(list2.item(i));
}
} else if (obj2 instanceof XML) {
listToAdd.addToList(obj2);
}
return listToAdd;
}
//
//
// Overriding XMLLib methods
//
//
/**
* See E4X 13.1.2.1.
*/
public boolean isXMLName(Context cx, Object nameObj)
{
String name;
try {
name = ScriptRuntime.toString(nameObj);
} catch (EcmaError ee) {
if ("TypeError".equals(ee.getName())) {
return false;
}
throw ee;
}
// See http://w3.org/TR/xml-names11/#NT-NCName
int length = name.length();
if (length != 0) {
if (isNCNameStartChar(name.charAt(0))) {
for (int i = 1; i != length; ++i) {
if (!isNCNameChar(name.charAt(i))) {
return false;
}
}
return true;
}
}
return false;
}
private static boolean isNCNameStartChar(int c)
{
if ((c & ~0x7F) == 0) {
// Optimize for ASCII and use A..Z < _ < a..z
if (c >= 'a') {
return c <= 'z';
} else if (c >= 'A') {
if (c <= 'Z') {
return true;
}
return c == '_';
}
} else if ((c & ~0x1FFF) == 0) {
return (0xC0 <= c && c <= 0xD6)
|| (0xD8 <= c && c <= 0xF6)
|| (0xF8 <= c && c <= 0x2FF)
|| (0x370 <= c && c <= 0x37D)
|| 0x37F <= c;
}
return (0x200C <= c && c <= 0x200D)
|| (0x2070 <= c && c <= 0x218F)
|| (0x2C00 <= c && c <= 0x2FEF)
|| (0x3001 <= c && c <= 0xD7FF)
|| (0xF900 <= c && c <= 0xFDCF)
|| (0xFDF0 <= c && c <= 0xFFFD)
|| (0x10000 <= c && c <= 0xEFFFF);
}
private static boolean isNCNameChar(int c)
{
if ((c & ~0x7F) == 0) {
// Optimize for ASCII and use - < . < 0..9 < A..Z < _ < a..z
if (c >= 'a') {
return c <= 'z';
} else if (c >= 'A') {
if (c <= 'Z') {
return true;
}
return c == '_';
} else if (c >= '0') {
return c <= '9';
} else {
return c == '-' || c == '.';
}
} else if ((c & ~0x1FFF) == 0) {
return isNCNameStartChar(c) || c == 0xB7
|| (0x300 <= c && c <= 0x36F);
}
return isNCNameStartChar(c) || (0x203F <= c && c <= 0x2040);
}
XMLName toQualifiedName(Context cx, Object namespaceValue,
Object nameValue)
{
// This is duplication of constructQName(cx, namespaceValue, nameValue)
// but for XMLName
String uri;
String localName;
if (nameValue instanceof QName) {
QName qname = (QName)nameValue;
localName = qname.localName();
} else {
localName = ScriptRuntime.toString(nameValue);
}
Namespace ns;
if (namespaceValue == Undefined.instance) {
if ("*".equals(localName)) {
ns = null;
} else {
ns = getDefaultNamespace(cx);
}
} else if (namespaceValue == null) {
ns = null;
} else if (namespaceValue instanceof Namespace) {
ns = (Namespace)namespaceValue;
} else {
ns = constructNamespace(cx, namespaceValue);
}
if (ns == null) {
uri = null;
} else {
uri = ns.uri();
}
return XMLName.formProperty(uri, localName);
}
public Ref nameRef(Context cx, Object name,
Scriptable scope, int memberTypeFlags)
{
if ((memberTypeFlags & Node.ATTRIBUTE_FLAG) == 0) {
// should only be called foir cases like @name or @[expr]
throw Kit.codeBug();
}
XMLName xmlName = toAttributeName(cx, name);
return xmlPrimaryReference(cx, xmlName, scope);
}
public Ref nameRef(Context cx, Object namespace, Object name,
Scriptable scope, int memberTypeFlags)
{
XMLName xmlName = toQualifiedName(cx, namespace, name);
if ((memberTypeFlags & Node.ATTRIBUTE_FLAG) != 0) {
if (!xmlName.isAttributeName()) {
xmlName.setAttributeName();
}
}
return xmlPrimaryReference(cx, xmlName, scope);
}
private Ref xmlPrimaryReference(Context cx, XMLName xmlName,
Scriptable scope)
{
XMLObjectImpl xmlObj;
XMLObjectImpl firstXmlObject = null;
for (;;) {
// XML object can only present on scope chain as a wrapper
// of XMLWithScope
if (scope instanceof XMLWithScope) {
xmlObj = (XMLObjectImpl)scope.getPrototype();
if (xmlObj.hasXMLProperty(xmlName)) {
break;
}
if (firstXmlObject == null) {
firstXmlObject = xmlObj;
}
}
scope = scope.getParentScope();
if (scope == null) {
xmlObj = firstXmlObject;
break;
}
}
// xmlObj == null corresponds to undefined as the target of
// the reference
if (xmlObj != null) {
xmlName.initXMLObject(xmlObj);
}
return xmlName;
}
/**
* Escapes the reserved characters in a value of an attribute
*
* @param value Unescaped text
* @return The escaped text
*/
public String escapeAttributeValue(Object value)
{
String text = ScriptRuntime.toString(value);
if (text.length() == 0) return "";
XmlObject xo = XmlObject.Factory.newInstance();
XmlCursor cursor = xo.newCursor();
cursor.toNextToken();
cursor.beginElement("a");
cursor.insertAttributeWithValue("a", text);
cursor.dispose();
String elementText = xo.toString();
int begin = elementText.indexOf('"');
int end = elementText.lastIndexOf('"');
return elementText.substring(begin + 1, end);
}
/**
* Escapes the reserved characters in a value of a text node
*
* @param value Unescaped text
* @return The escaped text
*/
public String escapeTextValue(Object value)
{
if (value instanceof XMLObjectImpl) {
return ((XMLObjectImpl)value).toXMLString(0);
}
String text = ScriptRuntime.toString(value);
if (text.length() == 0) return text;
XmlObject xo = XmlObject.Factory.newInstance();
XmlCursor cursor = xo.newCursor();
cursor.toNextToken();
cursor.beginElement("a");
cursor.insertChars(text);
cursor.dispose();
String elementText = xo.toString();
int begin = elementText.indexOf('>') + 1;
int end = elementText.lastIndexOf('<');
return (begin < end) ? elementText.substring(begin, end) : "";
}
public Object toDefaultXmlNamespace(Context cx, Object uriValue)
{
return constructNamespace(cx, uriValue);
}
}

View File

@@ -1,171 +0,0 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1999.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-2000
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Igor Bukanov
* Milen Nankov
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
package org.mozilla.javascript.xml.impl.xmlbeans;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.Kit;
import org.mozilla.javascript.Ref;
import org.mozilla.javascript.ScriptRuntime;
import org.mozilla.javascript.Undefined;
class XMLName extends Ref
{
static final long serialVersionUID = 3832176310755686977L;
private String uri;
private String localName;
private boolean isAttributeName;
private boolean isDescendants;
private XMLObjectImpl xmlObject;
private XMLName(String uri, String localName)
{
this.uri = uri;
this.localName = localName;
}
static XMLName formStar()
{
return new XMLName(null, "*");
}
static XMLName formProperty(String uri, String localName)
{
return new XMLName(uri, localName);
}
void initXMLObject(XMLObjectImpl xmlObject)
{
if (xmlObject == null) throw new IllegalArgumentException();
if (this.xmlObject != null) throw new IllegalStateException();
this.xmlObject = xmlObject;
}
String uri()
{
return uri;
}
String localName()
{
return localName;
}
boolean isAttributeName()
{
return isAttributeName;
}
void setAttributeName()
{
if (isAttributeName) throw new IllegalStateException();
isAttributeName = true;
}
boolean isDescendants()
{
return isDescendants;
}
void setIsDescendants()
{
if (isDescendants) throw new IllegalStateException();
isDescendants = true;
}
public boolean has(Context cx)
{
if (xmlObject == null) {
return false;
}
return xmlObject.hasXMLProperty(this);
}
public Object get(Context cx)
{
if (xmlObject == null) {
throw ScriptRuntime.undefReadError(Undefined.instance,
toString());
}
return xmlObject.getXMLProperty(this);
}
public Object set(Context cx, Object value)
{
if (xmlObject == null) {
throw ScriptRuntime.undefWriteError(Undefined.instance,
toString(),
value);
}
// Assignment to descendants causes parse error on bad reference
// and this should not be called
if (isDescendants) throw Kit.codeBug();
xmlObject.putXMLProperty(this, value);
return value;
}
public boolean delete(Context cx)
{
if (xmlObject == null) {
return true;
}
xmlObject.deleteXMLProperty(this);
return !xmlObject.hasXMLProperty(this);
}
public String toString()
{
//return qname.localName();
StringBuffer buff = new StringBuffer();
if (isDescendants) buff.append("..");
if (isAttributeName) buff.append('@');
if (uri == null) {
buff.append('*');
if(localName().equals("*")) {
return buff.toString();
}
} else {
buff.append('"').append(uri()).append('"');
}
buff.append(':').append(localName());
return buff.toString();
}
}

View File

@@ -1,724 +0,0 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1999.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-2000
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Igor Bukanov
* Ethan Hugg
* Terry Lucas
* Milen Nankov
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
package org.mozilla.javascript.xml.impl.xmlbeans;
import org.mozilla.javascript.*;
import org.mozilla.javascript.xml.*;
/**
* This abstract class describes what all XML objects (XML, XMLList) should have in common.
*
* @see XML
*/
abstract class XMLObjectImpl extends XMLObject
{
private static final Object XMLOBJECT_TAG = "XMLObject";
protected final XMLLibImpl lib;
protected boolean prototypeFlag;
protected XMLObjectImpl(XMLLibImpl lib, XMLObject prototype)
{
super(lib.globalScope(), prototype);
this.lib = lib;
}
/**
* ecmaHas(cx, id) calls this after resolving when id to XMLName
* and checking it is not Uint32 index.
*/
abstract boolean hasXMLProperty(XMLName name);
/**
* ecmaGet(cx, id) calls this after resolving when id to XMLName
* and checking it is not Uint32 index.
*/
abstract Object getXMLProperty(XMLName name);
/**
* ecmaPut(cx, id, value) calls this after resolving when id to XMLName
* and checking it is not Uint32 index.
*/
abstract void putXMLProperty(XMLName name, Object value);
/**
* ecmaDelete(cx, id) calls this after resolving when id to XMLName
* and checking it is not Uint32 index.
*/
abstract void deleteXMLProperty(XMLName name);
/**
* Test XML equality with target the target.
*/
abstract boolean equivalentXml(Object target);
// Methods from section 12.4.4 in the spec
abstract XML addNamespace(Namespace ns);
abstract XML appendChild(Object xml);
abstract XMLList attribute(XMLName xmlName);
abstract XMLList attributes();
abstract XMLList child(long index);
abstract XMLList child(XMLName xmlName);
abstract int childIndex();
abstract XMLList children();
abstract XMLList comments();
abstract boolean contains(Object xml);
abstract Object copy();
abstract XMLList descendants(XMLName xmlName);
abstract Object[] inScopeNamespaces();
abstract XML insertChildAfter(Object child, Object xml);
abstract XML insertChildBefore(Object child, Object xml);
abstract boolean hasOwnProperty(XMLName xmlName);
abstract boolean hasComplexContent();
abstract boolean hasSimpleContent();
abstract int length();
abstract String localName();
abstract QName name();
abstract Object namespace(String prefix);
abstract Object[] namespaceDeclarations();
abstract Object nodeKind();
abstract void normalize();
abstract Object parent();
abstract XML prependChild(Object xml);
abstract Object processingInstructions(XMLName xmlName);
abstract boolean propertyIsEnumerable(Object member);
abstract XML removeNamespace(Namespace ns);
abstract XML replace(long index, Object xml);
abstract XML replace(XMLName name, Object xml);
abstract XML setChildren(Object xml);
abstract void setLocalName(String name);
abstract void setName(QName xmlName);
abstract void setNamespace(Namespace ns);
abstract XMLList text();
public abstract String toString();
abstract String toSource(int indent);
abstract String toXMLString(int indent);
abstract Object valueOf();
/**
* Extension to access native implementation from scripts
*/
abstract org.apache.xmlbeans.XmlObject getXmlObject();
protected abstract Object jsConstructor(Context cx, boolean inNewExpr,
Object[] args);
final Object getMethod(String id)
{
return super.get(id, this);
}
//
//
// Methods overriding ScriptableObject
//
//
public final Object getDefaultValue(Class hint)
{
return toString();
}
public void delete(String name)
{
throw new IllegalArgumentException("String: [" + name + "]");
}
/**
* XMLObject always compare with any value and equivalentValues
* never returns {@link Scriptable#NOT_FOUND} for them but rather
* calls equivalentXml(value) and wrap the result as Boolean.
*/
protected final Object equivalentValues(Object value)
{
boolean result = equivalentXml(value);
return result ? Boolean.TRUE : Boolean.FALSE;
}
//
//
// Methods overriding XMLObject
//
//
public final XMLLib lib()
{
return lib;
}
/**
* Implementation of ECMAScript [[Has]]
*/
public final boolean ecmaHas(Context cx, Object id)
{
if (cx == null) cx = Context.getCurrentContext();
XMLName xmlName = lib.toXMLNameOrIndex(cx, id);
if (xmlName == null) {
long index = ScriptRuntime.lastUint32Result(cx);
// XXX Fix this cast
return has((int)index, this);
}
return hasXMLProperty(xmlName);
}
/**
* Implementation of ECMAScript [[Get]]
*/
public final Object ecmaGet(Context cx, Object id)
{
if (cx == null) cx = Context.getCurrentContext();
XMLName xmlName = lib.toXMLNameOrIndex(cx, id);
if (xmlName == null) {
long index = ScriptRuntime.lastUint32Result(cx);
// XXX Fix this cast
Object result = get((int)index, this);
if (result == Scriptable.NOT_FOUND) {
result = Undefined.instance;
}
return result;
}
return getXMLProperty(xmlName);
}
/**
* Implementation of ECMAScript [[Put]]
*/
public final void ecmaPut(Context cx, Object id, Object value)
{
if (cx == null) cx = Context.getCurrentContext();
XMLName xmlName = lib.toXMLNameOrIndex(cx, id);
if (xmlName == null) {
long index = ScriptRuntime.lastUint32Result(cx);
// XXX Fix this cast
put((int)index, this, value);
return;
}
putXMLProperty(xmlName, value);
}
/**
* Implementation of ECMAScript [[Delete]].
*/
public final boolean ecmaDelete(Context cx, Object id)
{
if (cx == null) cx = Context.getCurrentContext();
XMLName xmlName = lib.toXMLNameOrIndex(cx, id);
if (xmlName == null) {
long index = ScriptRuntime.lastUint32Result(cx);
// XXX Fix this
delete((int)index);
return true;
}
deleteXMLProperty(xmlName);
return true;
}
public Ref memberRef(Context cx, Object elem, int memberTypeFlags)
{
XMLName xmlName;
if ((memberTypeFlags & Node.ATTRIBUTE_FLAG) != 0) {
xmlName = lib.toAttributeName(cx, elem);
} else {
if ((memberTypeFlags & Node.DESCENDANTS_FLAG) == 0) {
// Code generation would use ecma(Get|Has|Delete|Set) for
// normal name idenrifiers so one ATTRIBUTE_FLAG
// or DESCENDANTS_FLAG has to be set
throw Kit.codeBug();
}
xmlName = lib.toXMLName(cx, elem);
}
if ((memberTypeFlags & Node.DESCENDANTS_FLAG) != 0) {
xmlName.setIsDescendants();
}
xmlName.initXMLObject(this);
return xmlName;
}
/**
* Generic reference to implement x::ns, x.@ns::y, x..@ns::y etc.
*/
public Ref memberRef(Context cx, Object namespace, Object elem,
int memberTypeFlags)
{
XMLName xmlName = lib.toQualifiedName(cx, namespace, elem);
if ((memberTypeFlags & Node.ATTRIBUTE_FLAG) != 0) {
if (!xmlName.isAttributeName()) {
xmlName.setAttributeName();
}
}
if ((memberTypeFlags & Node.DESCENDANTS_FLAG) != 0) {
xmlName.setIsDescendants();
}
xmlName.initXMLObject(this);
return xmlName;
}
public NativeWith enterWith(Scriptable scope)
{
return new XMLWithScope(lib, scope, this);
}
public NativeWith enterDotQuery(Scriptable scope)
{
XMLWithScope xws = new XMLWithScope(lib, scope, this);
xws.initAsDotQuery();
return xws;
}
public final Object addValues(Context cx, boolean thisIsLeft,
Object value)
{
if (value instanceof XMLObject) {
XMLObject v1, v2;
if (thisIsLeft) {
v1 = this;
v2 = (XMLObject)value;
} else {
v1 = (XMLObject)value;
v2 = this;
}
return lib.addXMLObjects(cx, v1, v2);
}
if (value == Undefined.instance) {
// both "xml + undefined" and "undefined + xml" gives String(xml)
return ScriptRuntime.toString(this);
}
return super.addValues(cx, thisIsLeft, value);
}
//
//
// IdScriptableObject machinery
//
//
final void exportAsJSClass(boolean sealed)
{
prototypeFlag = true;
exportAsJSClass(MAX_PROTOTYPE_ID, lib.globalScope(), sealed);
}
// #string_id_map#
private final static int
Id_constructor = 1,
Id_addNamespace = 2,
Id_appendChild = 3,
Id_attribute = 4,
Id_attributes = 5,
Id_child = 6,
Id_childIndex = 7,
Id_children = 8,
Id_comments = 9,
Id_contains = 10,
Id_copy = 11,
Id_descendants = 12,
Id_inScopeNamespaces = 13,
Id_insertChildAfter = 14,
Id_insertChildBefore = 15,
Id_hasOwnProperty = 16,
Id_hasComplexContent = 17,
Id_hasSimpleContent = 18,
Id_length = 19,
Id_localName = 20,
Id_name = 21,
Id_namespace = 22,
Id_namespaceDeclarations = 23,
Id_nodeKind = 24,
Id_normalize = 25,
Id_parent = 26,
Id_prependChild = 27,
Id_processingInstructions = 28,
Id_propertyIsEnumerable = 29,
Id_removeNamespace = 30,
Id_replace = 31,
Id_setChildren = 32,
Id_setLocalName = 33,
Id_setName = 34,
Id_setNamespace = 35,
Id_text = 36,
Id_toString = 37,
Id_toSource = 38,
Id_toXMLString = 39,
Id_valueOf = 40,
Id_getXmlObject = 41,
MAX_PROTOTYPE_ID = 41;
protected int findPrototypeId(String s)
{
int id;
// #generated# Last update: 2004-11-10 15:38:11 CET
L0: { id = 0; String X = null; int c;
L: switch (s.length()) {
case 4: c=s.charAt(0);
if (c=='c') { X="copy";id=Id_copy; }
else if (c=='n') { X="name";id=Id_name; }
else if (c=='t') { X="text";id=Id_text; }
break L;
case 5: X="child";id=Id_child; break L;
case 6: c=s.charAt(0);
if (c=='l') { X="length";id=Id_length; }
else if (c=='p') { X="parent";id=Id_parent; }
break L;
case 7: c=s.charAt(0);
if (c=='r') { X="replace";id=Id_replace; }
else if (c=='s') { X="setName";id=Id_setName; }
else if (c=='v') { X="valueOf";id=Id_valueOf; }
break L;
case 8: switch (s.charAt(4)) {
case 'K': X="nodeKind";id=Id_nodeKind; break L;
case 'a': X="contains";id=Id_contains; break L;
case 'd': X="children";id=Id_children; break L;
case 'e': X="comments";id=Id_comments; break L;
case 'r': X="toString";id=Id_toString; break L;
case 'u': X="toSource";id=Id_toSource; break L;
} break L;
case 9: switch (s.charAt(2)) {
case 'c': X="localName";id=Id_localName; break L;
case 'm': X="namespace";id=Id_namespace; break L;
case 'r': X="normalize";id=Id_normalize; break L;
case 't': X="attribute";id=Id_attribute; break L;
} break L;
case 10: c=s.charAt(0);
if (c=='a') { X="attributes";id=Id_attributes; }
else if (c=='c') { X="childIndex";id=Id_childIndex; }
break L;
case 11: switch (s.charAt(0)) {
case 'a': X="appendChild";id=Id_appendChild; break L;
case 'c': X="constructor";id=Id_constructor; break L;
case 'd': X="descendants";id=Id_descendants; break L;
case 's': X="setChildren";id=Id_setChildren; break L;
case 't': X="toXMLString";id=Id_toXMLString; break L;
} break L;
case 12: switch (s.charAt(0)) {
case 'a': X="addNamespace";id=Id_addNamespace; break L;
case 'g': X="getXmlObject";id=Id_getXmlObject; break L;
case 'p': X="prependChild";id=Id_prependChild; break L;
case 's': c=s.charAt(3);
if (c=='L') { X="setLocalName";id=Id_setLocalName; }
else if (c=='N') { X="setNamespace";id=Id_setNamespace; }
break L;
} break L;
case 14: X="hasOwnProperty";id=Id_hasOwnProperty; break L;
case 15: X="removeNamespace";id=Id_removeNamespace; break L;
case 16: c=s.charAt(0);
if (c=='h') { X="hasSimpleContent";id=Id_hasSimpleContent; }
else if (c=='i') { X="insertChildAfter";id=Id_insertChildAfter; }
break L;
case 17: c=s.charAt(3);
if (c=='C') { X="hasComplexContent";id=Id_hasComplexContent; }
else if (c=='c') { X="inScopeNamespaces";id=Id_inScopeNamespaces; }
else if (c=='e') { X="insertChildBefore";id=Id_insertChildBefore; }
break L;
case 20: X="propertyIsEnumerable";id=Id_propertyIsEnumerable; break L;
case 21: X="namespaceDeclarations";id=Id_namespaceDeclarations; break L;
case 22: X="processingInstructions";id=Id_processingInstructions; break L;
}
if (X!=null && X!=s && !X.equals(s)) id = 0;
}
// #/generated#
return id;
}
// #/string_id_map#
protected void initPrototypeId(int id)
{
String s;
int arity;
switch (id) {
case Id_constructor: {
IdFunctionObject ctor;
if (this instanceof XML) {
ctor = new XMLCtor((XML)this, XMLOBJECT_TAG, id, 1);
} else {
ctor = new IdFunctionObject(this, XMLOBJECT_TAG, id, 1);
}
initPrototypeConstructor(ctor);
return;
}
case Id_addNamespace: arity=1; s="addNamespace"; break;
case Id_appendChild: arity=1; s="appendChild"; break;
case Id_attribute: arity=1; s="attribute"; break;
case Id_attributes: arity=0; s="attributes"; break;
case Id_child: arity=1; s="child"; break;
case Id_childIndex: arity=0; s="childIndex"; break;
case Id_children: arity=0; s="children"; break;
case Id_comments: arity=0; s="comments"; break;
case Id_contains: arity=1; s="contains"; break;
case Id_copy: arity=0; s="copy"; break;
case Id_descendants: arity=1; s="descendants"; break;
case Id_hasComplexContent: arity=0; s="hasComplexContent"; break;
case Id_hasOwnProperty: arity=1; s="hasOwnProperty"; break;
case Id_hasSimpleContent: arity=0; s="hasSimpleContent"; break;
case Id_inScopeNamespaces: arity=0; s="inScopeNamespaces"; break;
case Id_insertChildAfter: arity=2; s="insertChildAfter"; break;
case Id_insertChildBefore: arity=2; s="insertChildBefore"; break;
case Id_length: arity=0; s="length"; break;
case Id_localName: arity=0; s="localName"; break;
case Id_name: arity=0; s="name"; break;
case Id_namespace: arity=1; s="namespace"; break;
case Id_namespaceDeclarations:
arity=0; s="namespaceDeclarations"; break;
case Id_nodeKind: arity=0; s="nodeKind"; break;
case Id_normalize: arity=0; s="normalize"; break;
case Id_parent: arity=0; s="parent"; break;
case Id_prependChild: arity=1; s="prependChild"; break;
case Id_processingInstructions:
arity=1; s="processingInstructions"; break;
case Id_propertyIsEnumerable:
arity=1; s="propertyIsEnumerable"; break;
case Id_removeNamespace: arity=1; s="removeNamespace"; break;
case Id_replace: arity=2; s="replace"; break;
case Id_setChildren: arity=1; s="setChildren"; break;
case Id_setLocalName: arity=1; s="setLocalName"; break;
case Id_setName: arity=1; s="setName"; break;
case Id_setNamespace: arity=1; s="setNamespace"; break;
case Id_text: arity=0; s="text"; break;
case Id_toString: arity=0; s="toString"; break;
case Id_toSource: arity=1; s="toSource"; break;
case Id_toXMLString: arity=1; s="toXMLString"; break;
case Id_valueOf: arity=0; s="valueOf"; break;
case Id_getXmlObject: arity=0; s="getXmlObject"; break;
default: throw new IllegalArgumentException(String.valueOf(id));
}
initPrototypeMethod(XMLOBJECT_TAG, id, s, arity);
}
/**
*
* @param f
* @param cx
* @param scope
* @param thisObj
* @param args
* @return
*/
public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
Scriptable thisObj, Object[] args)
{
if (!f.hasTag(XMLOBJECT_TAG)) {
return super.execIdCall(f, cx, scope, thisObj, args);
}
int id = f.methodId();
if (id == Id_constructor) {
return jsConstructor(cx, thisObj == null, args);
}
// All (XML|XMLList).prototype methods require thisObj to be XML
if (!(thisObj instanceof XMLObjectImpl))
throw incompatibleCallError(f);
XMLObjectImpl realThis = (XMLObjectImpl)thisObj;
switch (id) {
case Id_addNamespace: {
Namespace ns = lib.castToNamespace(cx, arg(args, 0));
return realThis.addNamespace(ns);
}
case Id_appendChild:
return realThis.appendChild(arg(args, 0));
case Id_attribute: {
XMLName xmlName = lib.toAttributeName(cx, arg(args, 0));
return realThis.attribute(xmlName);
}
case Id_attributes:
return realThis.attributes();
case Id_child: {
XMLName xmlName = lib.toXMLNameOrIndex(cx, arg(args, 0));
if (xmlName == null) {
long index = ScriptRuntime.lastUint32Result(cx);
return realThis.child(index);
} else {
return realThis.child(xmlName);
}
}
case Id_childIndex:
return ScriptRuntime.wrapInt(realThis.childIndex());
case Id_children:
return realThis.children();
case Id_comments:
return realThis.comments();
case Id_contains:
return ScriptRuntime.wrapBoolean(
realThis.contains(arg(args, 0)));
case Id_copy:
return realThis.copy();
case Id_descendants: {
XMLName xmlName = (args.length == 0)
? XMLName.formStar()
: lib.toXMLName(cx, args[0]);
return realThis.descendants(xmlName);
}
case Id_inScopeNamespaces: {
Object[] array = realThis.inScopeNamespaces();
return cx.newArray(scope, array);
}
case Id_insertChildAfter:
return realThis.insertChildAfter(arg(args, 0), arg(args, 1));
case Id_insertChildBefore:
return realThis.insertChildBefore(arg(args, 0), arg(args, 1));
case Id_hasOwnProperty: {
XMLName xmlName = lib.toXMLName(cx, arg(args, 0));
return ScriptRuntime.wrapBoolean(
realThis.hasOwnProperty(xmlName));
}
case Id_hasComplexContent:
return ScriptRuntime.wrapBoolean(realThis.hasComplexContent());
case Id_hasSimpleContent:
return ScriptRuntime.wrapBoolean(realThis.hasSimpleContent());
case Id_length:
return ScriptRuntime.wrapInt(realThis.length());
case Id_localName:
return realThis.localName();
case Id_name:
return realThis.name();
case Id_namespace: {
String prefix = (args.length > 0)
? ScriptRuntime.toString(args[0]) : null;
return realThis.namespace(prefix);
}
case Id_namespaceDeclarations: {
Object[] array = realThis.namespaceDeclarations();
return cx.newArray(scope, array);
}
case Id_nodeKind:
return realThis.nodeKind();
case Id_normalize:
realThis.normalize();
return Undefined.instance;
case Id_parent:
return realThis.parent();
case Id_prependChild:
return realThis.prependChild(arg(args, 0));
case Id_processingInstructions: {
XMLName xmlName = (args.length > 0)
? lib.toXMLName(cx, args[0])
: XMLName.formStar();
return realThis.processingInstructions(xmlName);
}
case Id_propertyIsEnumerable: {
return ScriptRuntime.wrapBoolean(
realThis.propertyIsEnumerable(arg(args, 0)));
}
case Id_removeNamespace: {
Namespace ns = lib.castToNamespace(cx, arg(args, 0));
return realThis.removeNamespace(ns);
}
case Id_replace: {
XMLName xmlName = lib.toXMLNameOrIndex(cx, arg(args, 0));
Object arg1 = arg(args, 1);
if (xmlName == null) {
long index = ScriptRuntime.lastUint32Result(cx);
return realThis.replace(index, arg1);
} else {
return realThis.replace(xmlName, arg1);
}
}
case Id_setChildren:
return realThis.setChildren(arg(args, 0));
case Id_setLocalName: {
String localName;
Object arg = arg(args, 0);
if (arg instanceof QName) {
localName = ((QName)arg).localName();
} else {
localName = ScriptRuntime.toString(arg);
}
realThis.setLocalName(localName);
return Undefined.instance;
}
case Id_setName: {
Object arg = (args.length != 0) ? args[0] : Undefined.instance;
QName qname;
if (arg instanceof QName) {
qname = (QName)arg;
if (qname.uri() == null) {
qname = lib.constructQNameFromString(cx, qname.localName());
} else {
// E4X 13.4.4.35 requires to always construct QName
qname = lib.constructQName(cx, qname);
}
} else {
qname = lib.constructQName(cx, arg);
}
realThis.setName(qname);
return Undefined.instance;
}
case Id_setNamespace: {
Namespace ns = lib.castToNamespace(cx, arg(args, 0));
realThis.setNamespace(ns);
return Undefined.instance;
}
case Id_text:
return realThis.text();
case Id_toString:
return realThis.toString();
case Id_toSource: {
int indent = ScriptRuntime.toInt32(args, 0);
return realThis.toSource(indent);
}
case Id_toXMLString: {
int indent = ScriptRuntime.toInt32(args, 0);
return realThis.toXMLString(indent);
}
case Id_valueOf:
return realThis.valueOf();
case Id_getXmlObject: {
org.apache.xmlbeans.XmlObject xmlObject = realThis.getXmlObject();
return Context.javaToJS(xmlObject, scope);
}
}
throw new IllegalArgumentException(String.valueOf(id));
}
private static Object arg(Object[] args, int i)
{
return (i < args.length) ? args[i] : Undefined.instance;
}
}

View File

@@ -1,125 +0,0 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1999.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Norris Boyd
* Ethan Hugg
* Terry Lucas
* Milen Nankov
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
package org.mozilla.javascript.xml.impl.xmlbeans;
import org.mozilla.javascript.*;
import org.mozilla.javascript.xml.*;
final class XMLWithScope extends NativeWith
{
private static final long serialVersionUID = -696429282095170887L;
private XMLLibImpl lib;
private int _currIndex;
private XMLList _xmlList;
private XMLObject _dqPrototype;
XMLWithScope(XMLLibImpl lib, Scriptable parent, XMLObject prototype)
{
super(parent, prototype);
this.lib = lib;
}
void initAsDotQuery()
{
XMLObject prototype = (XMLObject)getPrototype();
// XMLWithScope also handles the .(xxx) DotQuery for XML
// basically DotQuery is a for/in/with statement and in
// the following 3 statements we setup to signal it's
// DotQuery,
// the index and the object being looped over. The
// xws.setPrototype is the scope of the object which is
// is a element of the lhs (XMLList).
_currIndex = 0;
_dqPrototype = prototype;
if (prototype instanceof XMLList) {
XMLList xl = (XMLList)prototype;
if (xl.length() > 0) {
setPrototype((Scriptable)(xl.get(0, null)));
}
}
// Always return the outer-most type of XML lValue of
// XML to left of dotQuery.
_xmlList = new XMLList(lib);
}
protected Object updateDotQuery(boolean value)
{
// Return null to continue looping
XMLObject seed = _dqPrototype;
XMLList xmlL = _xmlList;
if (seed instanceof XMLList) {
// We're a list so keep testing each element of the list if the
// result on the top of stack is true then that element is added
// to our result list. If false, we try the next element.
XMLList orgXmlL = (XMLList)seed;
int idx = _currIndex;
if (value) {
xmlL.addToList(orgXmlL.get(idx, null));
}
// More elements to test?
if (++idx < orgXmlL.length()) {
// Yes, set our new index, get the next element and
// reset the expression to run with this object as
// the WITH selector.
_currIndex = idx;
setPrototype((Scriptable)(orgXmlL.get(idx, null)));
// continue looping
return null;
}
} else {
// If we're not a XMLList then there's no looping
// just return DQPrototype if the result is true.
if (value) {
xmlL.addToList(seed);
}
}
return xmlL;
}
}

View File

@@ -1,39 +1,20 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* License.
* NPL.
*
* The Original Code is Rhino code, released
* May 6, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
import org.mozilla.javascript.*;
@@ -41,7 +22,7 @@ import org.mozilla.javascript.*;
* Example of controlling the JavaScript execution engine.
*
* We evaluate a script and then manipulate the result.
*
*
*/
public class Control {
@@ -53,47 +34,60 @@ public class Control {
* Then set up the execution environment and begin to
* execute scripts.
*/
public static void main(String[] args)
{
public static void main(String[] args) {
Context cx = Context.enter();
// Set version to JavaScript1.2 so that we get object-literal style
// printing instead of "[object Object]"
cx.setLanguageVersion(Context.VERSION_1_2);
// Initialize the standard objects (Object, Function, etc.)
// This must be done before scripts can be executed.
Scriptable scope = cx.initStandardObjects(null);
// Now we can evaluate a script. Let's create a new object
// using the object literal notation.
Object result = null;
try {
// Set version to JavaScript1.2 so that we get object-literal style
// printing instead of "[object Object]"
cx.setLanguageVersion(Context.VERSION_1_2);
// Initialize the standard objects (Object, Function, etc.)
// This must be done before scripts can be executed.
Scriptable scope = cx.initStandardObjects();
// Now we can evaluate a script. Let's create a new object
// using the object literal notation.
Object result = cx.evaluateString(scope, "obj = {a:1, b:['x','y']}",
result = cx.evaluateString(scope, "obj = {a:1, b:['x','y']}",
"MySource", 1, null);
Scriptable obj = (Scriptable) scope.get("obj", scope);
// Should print "obj == result" (Since the result of an assignment
// expression is the value that was assigned)
System.out.println("obj " + (obj == result ? "==" : "!=") +
" result");
// Should print "obj.a == 1"
System.out.println("obj.a == " + obj.get("a", obj));
Scriptable b = (Scriptable) obj.get("b", obj);
// Should print "obj.b[0] == x"
System.out.println("obj.b[0] == " + b.get(0, b));
// Should print "obj.b[1] == y"
System.out.println("obj.b[1] == " + b.get(1, b));
// Should print {a:1, b:["x", "y"]}
Function fn = (Function) ScriptableObject.getProperty(obj, "toString");
System.out.println(fn.call(cx, scope, obj, new Object[0]));
} finally {
Context.exit();
}
catch (JavaScriptException jse) {
// ignore
}
FlattenedObject global = new FlattenedObject(scope);
FlattenedObject f = (FlattenedObject) global.getProperty("obj");
// Should print "obj == result" (Since the result of an assignment
// expression is the value that was assigned)
System.out.println("obj " + (f.getObject() == result ? "==" : "!=") +
" result");
// Should print "f.a == 1"
System.out.println("f.a == " + f.getProperty("a"));
FlattenedObject b = (FlattenedObject) f.getProperty("b");
// Should print "f.b[0] == x"
System.out.println("f.b[0] == " + b.getProperty(new Integer(0)));
// Should print "f.b[1] == y"
System.out.println("f.b[1] == " + b.getProperty(new Integer(1)));
try {
// Should print {a:1, b:["x", "y"]}
System.out.println(f.callMethod("toString", new Object[0]));
} catch (PropertyException e) {
// ignore
} catch (NotAFunctionException e) {
// ignore
} catch (JavaScriptException e) {
// ignore
}
cx.exit();
}
}

View File

@@ -1,62 +0,0 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Norris Boyd
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
import org.mozilla.javascript.*;
public class Counter extends ScriptableObject {
private static final long serialVersionUID = 438270592527335642L;
// The zero-argument constructor used by Rhino runtime to create instances
public Counter() { }
// Method jsConstructor defines the JavaScript constructor
public void jsConstructor(int a) { count = a; }
// The class name is defined by the getClassName method
@Override
public String getClassName() { return "Counter"; }
// The method jsGet_count defines the count property.
public int jsGet_count() { return count++; }
// Methods can be defined using the jsFunction_ prefix. Here we define
// resetCount for JavaScript.
public void jsFunction_resetCount() { count = 0; }
private int count;
}

View File

@@ -1,82 +0,0 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Norris Boyd
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
import org.mozilla.javascript.*;
/**
* An example illustrating how to create a JavaScript object and retrieve
* properties and call methods.
* <p>
* Output should be:
* <pre>
* count = 0
* count = 1
* resetCount
* count = 0
* </pre>
*/
public class CounterTest {
public static void main(String[] args) throws Exception
{
Context cx = Context.enter();
try {
Scriptable scope = cx.initStandardObjects();
ScriptableObject.defineClass(scope, Counter.class);
Scriptable testCounter = cx.newObject(scope, "Counter");
Object count = ScriptableObject.getProperty(testCounter, "count");
System.out.println("count = " + count);
count = ScriptableObject.getProperty(testCounter, "count");
System.out.println("count = " + count);
ScriptableObject.callMethod(testCounter,
"resetCount",
new Object[0]);
System.out.println("resetCount");
count = ScriptableObject.getProperty(testCounter, "count");
System.out.println("count = " + count);
} finally {
Context.exit();
}
}
}

View File

@@ -1,205 +0,0 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-2000
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Norris Boyd
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
import org.mozilla.javascript.*;
/**
* Example of controlling the JavaScript with multiple scopes and threads.
*/
public class DynamicScopes {
static boolean useDynamicScope;
static class MyFactory extends ContextFactory
{
@Override
protected boolean hasFeature(Context cx, int featureIndex)
{
if (featureIndex == Context.FEATURE_DYNAMIC_SCOPE) {
return useDynamicScope;
}
return super.hasFeature(cx, featureIndex);
}
}
static {
ContextFactory.initGlobal(new MyFactory());
}
/**
* Main entry point.
*
* Set up the shared scope and then spawn new threads that execute
* relative to that shared scope. Try to run functions with and
* without dynamic scope to see the effect.
*
* The expected output is
* <pre>
* sharedScope
* nested:sharedScope
* sharedScope
* nested:sharedScope
* sharedScope
* nested:sharedScope
* thread0
* nested:thread0
* thread1
* nested:thread1
* thread2
* nested:thread2
* </pre>
* The final three lines may be permuted in any order depending on
* thread scheduling.
*/
public static void main(String[] args)
{
Context cx = Context.enter();
try {
// Precompile source only once
String source = ""
+"var x = 'sharedScope';\n"
+"function f() { return x; }\n"
// Dynamic scope works with nested function too
+"function initClosure(prefix) {\n"
+" return function test() { return prefix+x; }\n"
+"}\n"
+"var closure = initClosure('nested:');\n"
+"";
Script script = cx.compileString(source, "sharedScript", 1, null);
useDynamicScope = false;
runScripts(cx, script);
useDynamicScope = true;
runScripts(cx, script);
} finally {
Context.exit();
}
}
static void runScripts(Context cx, Script script)
{
// Initialize the standard objects (Object, Function, etc.)
// This must be done before scripts can be executed. The call
// returns a new scope that we will share.
ScriptableObject sharedScope = cx.initStandardObjects(null, true);
// Now we can execute the precompiled script against the scope
// to define x variable and f function in the shared scope.
script.exec(cx, sharedScope);
// Now we spawn some threads that execute a script that calls the
// function 'f'. The scope chain looks like this:
// <pre>
// ------------------ ------------------
// | per-thread scope | -prototype-> | shared scope |
// ------------------ ------------------
// ^
// |
// parentScope
// |
// ------------------
// | f's activation |
// ------------------
// </pre>
// Both the shared scope and the per-thread scope have variables 'x'
// defined in them. If 'f' is compiled with dynamic scope enabled,
// the 'x' from the per-thread scope will be used. Otherwise, the 'x'
// from the shared scope will be used. The 'x' defined in 'g' (which
// calls 'f') should not be seen by 'f'.
final int threadCount = 3;
Thread[] t = new Thread[threadCount];
for (int i=0; i < threadCount; i++) {
String source2 = ""
+"function g() { var x = 'local'; return f(); }\n"
+"java.lang.System.out.println(g());\n"
+"function g2() { var x = 'local'; return closure(); }\n"
+"java.lang.System.out.println(g2());\n"
+"";
t[i] = new Thread(new PerThread(sharedScope, source2,
"thread" + i));
}
for (int i=0; i < threadCount; i++)
t[i].start();
// Don't return in this thread until all the spawned threads have
// completed.
for (int i=0; i < threadCount; i++) {
try {
t[i].join();
} catch (InterruptedException e) {
}
}
}
static class PerThread implements Runnable {
PerThread(Scriptable sharedScope, String source, String x) {
this.sharedScope = sharedScope;
this.source = source;
this.x = x;
}
public void run() {
// We need a new Context for this thread.
Context cx = Context.enter();
try {
// We can share the scope.
Scriptable threadScope = cx.newObject(sharedScope);
threadScope.setPrototype(sharedScope);
// We want "threadScope" to be a new top-level
// scope, so set its parent scope to null. This
// means that any variables created by assignments
// will be properties of "threadScope".
threadScope.setParentScope(null);
// Create a JavaScript property of the thread scope named
// 'x' and save a value for it.
threadScope.put("x", threadScope, x);
cx.evaluateString(threadScope, source, "threadScript", 1, null);
} finally {
Context.exit();
}
}
private Scriptable sharedScope;
private String source;
private String x;
}
}

View File

@@ -1,223 +0,0 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1999.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* John Schneider
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
print("----------------------------------------");
// Use the XML constructor to parse an string into an XML object
var John = "<employee><name>John</name><age>25</age></employee>";
var Sue ="<employee><name>Sue</name><age>32</age></employee>";
var tagName = "employees";
var employees = new XML("<" + tagName +">" + John + Sue + "</" + tagName +">");
print("The employees XML object constructed from a string is:\n" + employees);
print("----------------------------------------");
// Use an XML literal to create an XML object
var order = <order>
<customer>
<firstname>John</firstname>
<lastname>Doe</lastname>
</customer>
<item>
<description>Big Screen Television</description>
<price>1299.99</price>
<quantity>1</quantity>
</item>
</order>
// Construct the full customer name
var name = order.customer.firstname + " " + order.customer.lastname;
// Calculate the total price
var total = order.item.price * order.item.quantity;
print("The order XML object constructed using a literal is:\n" + order);
print("The total price of " + name + "'s order is " + total);
print("----------------------------------------");
// construct a new XML object using expando and super-expando properties
var order = <order/>;
order.customer.name = "Fred Jones";
order.customer.address.street = "123 Long Lang";
order.customer.address.city = "Underwood";
order.customer.address.state = "CA";
order.item[0] = "";
order.item[0].description = "Small Rodents";
order.item[0].quantity = 10;
order.item[0].price = 6.95;
print("The order custructed using expandos and super-expandos is:\n" + order);
// append a new item to the order
order.item += <item><description>Catapult</description><price>139.95</price></item>;
print("----------------------------------------");
print("The order after appending a new item is:\n" + order);
print("----------------------------------------");
// dynamically construct an XML element using embedded expressions
var tagname = "name";
var attributename = "id";
var attributevalue = 5;
var content = "Fred";
var x = <{tagname} {attributename}={attributevalue}>{content}</{tagname}>;
print("The dynamically computed element value is:\n" + x.toXMLString());
print("----------------------------------------");
// Create a SOAP message
var message = <soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<soap:Body>
<m:GetLastTradePrice xmlns:m="http://mycompany.com/stocks">
<symbol>DIS</symbol>
</m:GetLastTradePrice>
</soap:Body>
</soap:Envelope>
// declare the SOAP and stocks namespaces
var soap = new Namespace("http://schemas.xmlsoap.org/soap/envelope/");
var stock = new Namespace ("http://mycompany.com/stocks");
// extract the soap encoding style and body from the soap message
var encodingStyle = message.@soap::encodingStyle;
print("The encoding style of the soap message is specified by:\n" + encodingStyle);
// change the stock symbol
message.soap::Body.stock::GetLastTradePrice.symbol = "MYCO";
var body = message.soap::Body;
print("The body of the soap message is:\n" + body);
print("----------------------------------------");
// create an manipulate an XML object using the default xml namespace
default xml namespace = "http://default.namespace.com";
var x = <x/>;
x.a = "one";
x.b = "two";
x.c = <c xmlns="http://some.other.namespace.com">three</c>;
print("XML object constructed using the default xml namespace:\n" + x);
default xml namespace="";
print("----------------------------------------");
var order = <order id = "123456" timestamp="Mon Mar 10 2003 16:03:25 GMT-0800 (PST)">
<customer>
<firstname>John</firstname>
<lastname>Doe</lastname>
</customer>
<item id="3456">
<description>Big Screen Television</description>
<price>1299.99</price>
<quantity>1</quantity>
</item>
<item id = "56789">
<description>DVD Player</description>
<price>399.99</price>
<quantity>1</quantity>
</item>
</order>;
// get the customer element from the orderprint("The customer is:\n" + order.customer);
// get the id attribute from the order
print("The order id is:" + order.@id);
// get all the child elements from the order element
print("The children of the order are:\n" + order.*);
// get the list of all item descriptions
print("The order descriptions are:\n" + order.item.description);
// get second item by numeric index
print("The second item is:\n" + order.item[1]);
// get the list of all child elements in all item elements
print("The children of the items are:\n" + order.item.*);
// get the second child element from the order by index
print("The second child of the order is:\n" + order.*[1]);
// calculate the total price of the order
var totalprice = 0;
for each (i in order.item) {
totalprice += i.price * i.quantity;
}
print("The total price of the order is: " + totalprice);
print("----------------------------------------");
var e = <employees>
<employee id="1"><name>Joe</name><age>20</age></employee>
<employee id="2"><name>Sue</name><age>30</age></employee>
</employees>;
// get all the names in e
print("All the employee names are:\n" + e..name);
// employees with name Joe
print("The employee named Joe is:\n" + e.employee.(name == "Joe"));
// employees with id's 1 & 2
print("Employees with ids 1 & 2:\n" + e.employee.(@id == 1 || @id == 2));
// name of employee with id 1
print("Name of the the employee with ID=1: " + e.employee.(@id == 1).name);
print("----------------------------------------");

View File

@@ -1,45 +1,24 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* License.
* NPL.
*
* The Original Code is Rhino code, released
* May 6, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-2000
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Norris Boyd
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
import org.mozilla.javascript.*;
import java.io.*;
import java.util.List;
import java.util.ArrayList;
import java.util.Vector;
/**
* Define a simple JavaScript File object.
@@ -51,6 +30,7 @@ import java.util.ArrayList;
* Example of use of the File object:
* <pre>
* js> defineClass("File")
* js> var file = new File("myfile.txt");
* js> file = new File("myfile.txt");
* [object File]
* js> file.writeLine("one"); <i>only now is file actually opened</i>
@@ -68,14 +48,10 @@ import java.util.ArrayList;
* be wrapped as JavaScript exceptions when called from JavaScript,
* and may be caught within JavaScript.
*
* @author Norris Boyd
* @author Norris Boyd
*/
public class File extends ScriptableObject {
/**
*
*/
private static final long serialVersionUID = 2549960399774237828L;
/**
* The zero-parameter constructor.
*
@@ -95,9 +71,8 @@ public class File extends ScriptableObject {
* Otherwise System.in or System.out is assumed as appropriate
* to the use.
*/
public static Scriptable jsConstructor(Context cx, Object[] args,
Function ctorObj,
boolean inNewExpr)
public static Scriptable js_File(Context cx, Object[] args,
Function ctorObj, boolean inNewExpr)
{
File result = new File();
if (args.length == 0 || args[0] == Context.getUndefinedValue()) {
@@ -113,7 +88,6 @@ public class File extends ScriptableObject {
/**
* Returns the name of this JavaScript class, "File".
*/
@Override
public String getClassName() {
return "File";
}
@@ -123,7 +97,7 @@ public class File extends ScriptableObject {
*
* Used to define the "name" property.
*/
public String jsGet_name() {
public String js_getName() {
return name;
}
@@ -137,19 +111,32 @@ public class File extends ScriptableObject {
*
* @exception IOException if an error occurred while accessing the file
* associated with this object
* @exception JavaScriptException if a JavaScript exception occurred
* while creating the result array
*/
public Object jsFunction_readLines()
throws IOException
public Object js_readLines()
throws IOException, JavaScriptException
{
List<String> list = new ArrayList<String>();
Vector v = new Vector();
String s;
while ((s = jsFunction_readLine()) != null) {
list.add(s);
while ((s = js_readLine()) != null) {
v.addElement(s);
}
String[] lines = list.toArray(new String[list.size()]);
Object[] lines = new Object[v.size()];
v.copyInto(lines);
Scriptable scope = ScriptableObject.getTopLevelScope(this);
Context cx = Context.getCurrentContext();
return cx.newObject(scope, "Array", lines);
Scriptable result;
try {
Context cx = Context.getCurrentContext();
result = cx.newObject(scope, "Array", lines);
} catch (PropertyException e) {
throw Context.reportRuntimeError(e.getMessage());
} catch (NotAFunctionException e) {
throw Context.reportRuntimeError(e.getMessage());
}
return result;
}
/**
@@ -160,7 +147,7 @@ public class File extends ScriptableObject {
* associated with this object, or EOFException if the object
* reached the end of the file
*/
public String jsFunction_readLine() throws IOException {
public String js_readLine() throws IOException {
return getReader().readLine();
}
@@ -171,7 +158,22 @@ public class File extends ScriptableObject {
* associated with this object, or EOFException if the object
* reached the end of the file
*/
public String jsFunction_readChar() throws IOException {
public String js_readChar() throws IOException {
int i = getReader().read();
if (i == -1)
return null;
char[] charArray = { (char) i };
return new String(charArray);
}
/**
* Read a block.
*
* @exception IOException if an error occurred while accessing the file
* associated with this object, or EOFException if the object
* reached the end of the file
*/
public String js_readBlock() throws IOException {
int i = getReader().read();
if (i == -1)
return null;
@@ -189,8 +191,8 @@ public class File extends ScriptableObject {
* @exception IOException if an error occurred while accessing the file
* associated with this object
*/
public static void jsFunction_write(Context cx, Scriptable thisObj,
Object[] args, Function funObj)
public static void js_write(Context cx, Scriptable thisObj,
Object[] args, Function funObj)
throws IOException
{
write0(thisObj, args, false);
@@ -204,14 +206,14 @@ public class File extends ScriptableObject {
* associated with this object
*
*/
public static void jsFunction_writeLine(Context cx, Scriptable thisObj,
Object[] args, Function funObj)
public static void js_writeLine(Context cx, Scriptable thisObj,
Object[] args, Function funObj)
throws IOException
{
write0(thisObj, args, true);
}
public int jsGet_lineNumber()
public int js_getLineNumber()
throws FileNotFoundException
{
return getReader().getLineNumber();
@@ -224,7 +226,7 @@ public class File extends ScriptableObject {
* @exception IOException if an error occurred while accessing the file
* associated with this object
*/
public void jsFunction_close() throws IOException {
public void js_close() throws IOException {
if (reader != null) {
reader.close();
reader = null;
@@ -239,10 +241,9 @@ public class File extends ScriptableObject {
*
* Close the file when this object is collected.
*/
@Override
protected void finalize() {
public void finalize() {
try {
jsFunction_close();
js_close();
}
catch (IOException e) {
}
@@ -250,6 +251,11 @@ public class File extends ScriptableObject {
/**
* Get the Java reader.
*
* Note that we use the name "jsFunction_getReader" because if we
* used just "js_getReader" we'd be defining a readonly property
* named "reader".
*
*/
public Object jsFunction_getReader() {
if (reader == null)
@@ -258,7 +264,7 @@ public class File extends ScriptableObject {
// in a Scriptable object so that it can be manipulated by
// JavaScript.
Scriptable parent = ScriptableObject.getTopLevelScope(this);
return Context.javaToJS(reader, parent);
return Context.toObject(reader, parent);
}
/**
@@ -271,7 +277,7 @@ public class File extends ScriptableObject {
if (writer == null)
return null;
Scriptable parent = ScriptableObject.getTopLevelScope(this);
return Context.javaToJS(writer, parent);
return Context.toObject(writer, parent);
}
/**

View File

@@ -1,39 +1,20 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* License.
* NPL.
*
* The Original Code is Rhino code, released
* May 6, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
import org.mozilla.javascript.*;
@@ -79,7 +60,6 @@ import org.mozilla.javascript.*;
*/
public class Foo extends ScriptableObject {
private static final long serialVersionUID = -3833489808933339159L;
/**
* The zero-parameter constructor.
@@ -107,7 +87,6 @@ public class Foo extends ScriptableObject {
/**
* Returns the name of this JavaScript class, "Foo".
*/
@Override
public String getClassName() {
return "Foo";
}
@@ -145,6 +124,8 @@ public class Foo extends ScriptableObject {
* @return computes the string values and types of 'this' and
* of each of the supplied arguments and returns them in a string.
*
* @exception ThreadAssociationException if the current
* thread is not associated with a Context
* @see org.mozilla.javascript.ScriptableObject#getTopLevelScope
*/
public static Object jsFunction_varargs(Context cx, Scriptable thisObj,

View File

@@ -0,0 +1,43 @@
#! gmake
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1999 Netscape Communications Corporation. All Rights
# Reserved.
#
# Makefile for the examples directory.
#
# This Makefile just calls $(JAVAC) on all the .java files. This
# Makefile is intended to be called from the toplevel Makefile.
#
JSFILES = $(PATH_PREFIX)/*.js
SOURCES = $(PATH_PREFIX)/*.java
CLASSES = $(PATH_PREFIX)/*.class
$(CLASSES) : $(SOURCES)
$(JAVAC) $(JFLAGS) $(SOURCES)
clean :
- rm $(CLASSES) $(PATH_PREFIX)/MANIFEST
clobber : clean
check :
$(PATH_PREFIX)/MANIFEST : $(SOURCES) $(CLASSES) $(JSFILES)
ls $(SOURCES) $(CLASSES) $(JSFILES) \
> $(@)
# Emulate .PHONY
FORCE :

View File

@@ -1,43 +1,23 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* License.
* NPL.
*
* The Original Code is Rhino code, released
* May 6, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
import org.mozilla.javascript.*;
import java.util.List;
import java.util.ArrayList;
import java.util.Vector;
/**
* Matrix: An example host object class that implements the Scriptable interface.
@@ -52,20 +32,21 @@ import java.util.ArrayList;
* Here's a shell session showing the Matrix object in action:
* <pre>
* js> defineClass("Matrix")
* js> var m = new Matrix(2); // A constructor call, see "Matrix(int dimension)"
* js> m // Object.toString will call "Matrix.getClassName()"
* [object Matrix]
* js> m = new Matrix(2); <i>A constructor call, see <a href="#Matrix">Matrix</a> below.</i>
* [object Matrix] <i>The "Matrix" here comes from <a href"#getClassName">getClassName</a>.</i>
* js> version(120); <i>switch to JavaScript1.2 to see arrays better</i>
* 0
* js> m[0][0] = 3;
* 3
* js> uneval(m[0]); // an array was created automatically!
* js> m[0]; <i>an array was created automatically!</i>
* [3]
* js> uneval(m[1]); // array is created even if we don't set a value
* js> m[1]; <i>array is created even if we don't set a value</i>
* []
* js> m.dim; // we can access the "dim" property
* js> m.dim; <i>we can access the "dim" property</i>
* 2
* js> m.dim = 3;
* 3
* js> m.dim; // but not modify the "dim" property
* js> m.dim; <i>but not modify it</i>
* 2
* </pre>
*
@@ -79,7 +60,7 @@ public class Matrix implements Scriptable {
/**
* The zero-parameter constructor.
*
* When ScriptableObject.defineClass is called with this class, it will
* When Context.defineClass is called with this class, it will
* construct Matrix.prototype using this constructor.
*/
public Matrix() {
@@ -94,7 +75,7 @@ public class Matrix implements Scriptable {
"Dimension of Matrix must be greater than zero");
}
dim = dimension;
list = new ArrayList<Object>();
v = new Vector();
}
/**
@@ -146,16 +127,15 @@ public class Matrix implements Scriptable {
/**
* Get the indexed property.
* <p>
* Look up the element in the associated list and return
* Look up the element in the associated vector and return
* it if it exists. If it doesn't exist, create it.<p>
* @param index the index of the integral property
* @param start the object where the lookup began
*/
public Object get(int index, Scriptable start) {
while (index >= list.size()) {
list.add(null);
}
Object result = list.get(index);
if (index >= v.size())
v.setSize(index+1);
Object result = v.elementAt(index);
if (result != null)
return result;
if (dim > 2) {
@@ -168,7 +148,7 @@ public class Matrix implements Scriptable {
Scriptable scope = ScriptableObject.getTopLevelScope(start);
result = cx.newArray(scope, 0);
}
list.set(index, result);
v.setElementAt(result, index);
return result;
}
@@ -249,7 +229,7 @@ public class Matrix implements Scriptable {
* Use the convenience method from Context that takes care of calling
* toString, etc.
*/
public Object getDefaultValue(Class<?> typeHint) {
public Object getDefaultValue(Class typeHint) {
return "[object Matrix]";
}
@@ -263,9 +243,7 @@ public class Matrix implements Scriptable {
public boolean hasInstance(Scriptable value) {
Scriptable proto = value.getPrototype();
while (proto != null) {
if (proto.equals(this))
return true;
proto = proto.getPrototype();
if (proto.equals(this)) return true;
}
return false;
@@ -275,6 +253,6 @@ public class Matrix implements Scriptable {
* Some private data for this class.
*/
private int dim;
private List<Object> list;
private Vector v;
private Scriptable prototype, parent;
}

View File

@@ -1,53 +0,0 @@
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Rhino code, released May 6, 1999.
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation.
- Portions created by the Initial Developer are Copyright (C) 1997-1999
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
-
- Alternatively, the contents of this file may be used under the terms of
- the GNU General Public License Version 2 or later (the "GPL"), in which
- case the provisions of the GPL are applicable instead of those above. If
- you wish to allow use of your version of this file only under the terms of
- the GPL and not to allow others to use your version of this file under the
- MPL, indicate your decision by deleting the provisions above and replacing
- them with the notice and other provisions required by the GPL. If you do
- not delete the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
-
- ***** END LICENSE BLOCK ***** -->
<html>
<body>
This is the NervousText applet in javascript:
<applet archive="js.jar" code=NervousText width=200 height=50 >
</applet>
<hr>
The test assumes that applet code is generated with:
<pre>
java -classpath js.jar org.mozilla.javascript.tools.jsc.Main \
-extends java.applet.Applet \
-implements java.lang.Runnable \
NervousText.js
</pre>
and the resulting 2 classes, NervousText.class extending java.applet.Applet and implementing java.lang.Runnable and NervousText1.class which represents compiled JavaScript code, are placed in the same directory as NervousText.html.
<p>
The test also assumes that js.jar from Rhino distribution is available in the same directory.
</body>
</html>

View File

@@ -1,109 +0,0 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released May 6, 1999.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
// The Java "NervousText" example ported to JavaScript.
// Compile using java org.mozilla.javascript.tools.jsc.Main -extends java.applet.Applet -implements java.lang.Runnable NervousText.js
/*
Adapted from Java code by
Daniel Wyszynski
Center for Applied Large-Scale Computing (CALC)
04-12-95
Test of text animation.
kwalrath: Changed string; added thread suspension. 5-9-95
*/
var Font = java.awt.Font;
var Thread = java.lang.Thread;
var separated;
var s = null;
var killme = null;
var i;
var x_coord = 0, y_coord = 0;
var num;
var speed=35;
var counter =0;
var threadSuspended = false; //added by kwalrath
function init() {
this.resize(150,50);
this.setFont(new Font("TimesRoman",Font.BOLD,36));
s = this.getParameter("text");
if (s == null) {
s = "Rhino";
}
separated = s.split('');
}
function start() {
if(killme == null)
{
killme = new java.lang.Thread(java.lang.Runnable(this));
killme.start();
}
}
function stop() {
killme = null;
}
function run() {
while (killme != null) {
try {Thread.sleep(100);} catch (e){}
this.repaint();
}
killme = null;
}
function paint(g) {
for(i=0;i<separated.length;i++)
{
x_coord = Math.random()*10+15*i;
y_coord = Math.random()*10+36;
g.drawChars(separated, i,1,x_coord,y_coord);
}
}
/* Added by kwalrath. */
function mouseDown(evt, x, y) {
if (threadSuspended) {
killme.resume();
}
else {
killme.suspend();
}
threadSuspended = !threadSuspended;
return true;
}

View File

@@ -1,72 +0,0 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Norris Boyd
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
import org.mozilla.javascript.*;
/**
* An example WrapFactory that can be used to avoid wrapping of Java types
* that can be converted to ECMA primitive values.
* So java.lang.String is mapped to ECMA string, all java.lang.Numbers are
* mapped to ECMA numbers, and java.lang.Booleans are mapped to ECMA booleans
* instead of being wrapped as objects. Additionally java.lang.Character is
* converted to ECMA string with length 1.
* Other types have the default behavior.
* <p>
* Note that calling "new java.lang.String('foo')" in JavaScript with this
* wrap factory enabled will still produce a wrapped Java object since the
* WrapFactory.wrapNewObject method is not overridden.
* <p>
* The PrimitiveWrapFactory is enabled on a Context by calling setWrapFactory
* on that context.
*/
public class PrimitiveWrapFactory extends WrapFactory {
@Override
public Object wrap(Context cx, Scriptable scope, Object obj,
Class<?> staticType)
{
if (obj instanceof String || obj instanceof Number ||
obj instanceof Boolean)
{
return obj;
} else if (obj instanceof Character) {
char[] a = { ((Character)obj).charValue() };
return new String(a);
}
return super.wrap(cx, scope, obj, staticType);
}
}

View File

@@ -1,78 +1,57 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* License.
* NPL.
*
* The Original Code is Rhino code, released
* May 6, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
import org.mozilla.javascript.*;
/**
* RunScript: simplest example of controlling execution of Rhino.
*
* Collects its arguments from the command line, executes the
*
* Collects its arguments from the command line, executes the
* script, and prints the result.
*
*
* @author Norris Boyd
*/
public class RunScript {
public static void main(String args[])
public static void main(String args[])
throws JavaScriptException
{
// Creates and enters a Context. The Context stores information
// about the execution environment of a script.
Context cx = Context.enter();
try {
// Initialize the standard objects (Object, Function, etc.)
// This must be done before scripts can be executed. Returns
// a scope object that we use in later calls.
Scriptable scope = cx.initStandardObjects();
// Collect the arguments into a single string.
String s = "";
for (int i=0; i < args.length; i++) {
s += args[i];
}
// Now evaluate the string we've colected.
Object result = cx.evaluateString(scope, s, "<cmd>", 1, null);
// Convert the result to a string and print it.
System.err.println(Context.toString(result));
} finally {
// Exit from the context.
Context.exit();
}
// Initialize the standard objects (Object, Function, etc.)
// This must be done before scripts can be executed. Returns
// a scope object that we use in later calls.
Scriptable scope = cx.initStandardObjects(null);
// Collect the arguments into a single string.
String s = "";
for (int i=0; i < args.length; i++)
s += args[i];
// Now evaluate the string we've colected.
Object result = cx.evaluateString(scope, s, "<cmd>", 1, null);
// Convert the result to a string and print it.
System.err.println(cx.toString(result));
// Exit from the context.
Context.exit();
}
}

View File

@@ -1,69 +0,0 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
import org.mozilla.javascript.*;
/**
* RunScript2: Like RunScript, but reflects the System.out into JavaScript.
*
* @author Norris Boyd
*/
public class RunScript2 {
public static void main(String args[])
{
Context cx = Context.enter();
try {
Scriptable scope = cx.initStandardObjects();
// Add a global variable "out" that is a JavaScript reflection
// of System.out
Object jsOut = Context.javaToJS(System.out, scope);
ScriptableObject.putProperty(scope, "out", jsOut);
String s = "";
for (int i=0; i < args.length; i++) {
s += args[i];
}
Object result = cx.evaluateString(scope, s, "<cmd>", 1, null);
System.err.println(Context.toString(result));
} finally {
Context.exit();
}
}
}

View File

@@ -1,88 +0,0 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
import org.mozilla.javascript.*;
/**
* RunScript3: Example of using JavaScript objects
*
* Collects its arguments from the command line, executes the
* script, and then ...
*
* @author Norris Boyd
*/
public class RunScript3 {
public static void main(String args[])
{
Context cx = Context.enter();
try {
Scriptable scope = cx.initStandardObjects();
// Collect the arguments into a single string.
String s = "";
for (int i=0; i < args.length; i++) {
s += args[i];
}
// Now evaluate the string we've collected. We'll ignore the result.
cx.evaluateString(scope, s, "<cmd>", 1, null);
// Print the value of variable "x"
Object x = scope.get("x", scope);
if (x == Scriptable.NOT_FOUND) {
System.out.println("x is not defined.");
} else {
System.out.println("x = " + Context.toString(x));
}
// Call function "f('my arg')" and print its result.
Object fObj = scope.get("f", scope);
if (!(fObj instanceof Function)) {
System.out.println("f is undefined or not a function.");
} else {
Object functionArgs[] = { "my arg" };
Function f = (Function)fObj;
Object result = f.call(cx, scope, scope, functionArgs);
String report = "f('my args') = " + Context.toString(result);
System.out.println(report);
}
} finally {
Context.exit();
}
}
}

View File

@@ -1,78 +0,0 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
import org.mozilla.javascript.*;
/**
* RunScript4: Execute scripts in an environment that includes the
* example Counter class.
*
* @author Norris Boyd
*/
public class RunScript4 {
public static void main(String args[])
throws Exception
{
Context cx = Context.enter();
try {
Scriptable scope = cx.initStandardObjects();
// Use the Counter class to define a Counter constructor
// and prototype in JavaScript.
ScriptableObject.defineClass(scope, Counter.class);
// Create an instance of Counter and assign it to
// the top-level variable "myCounter". This is
// equivalent to the JavaScript code
// myCounter = new Counter(7);
Object[] arg = { new Integer(7) };
Scriptable myCounter = cx.newObject(scope, "Counter", arg);
scope.put("myCounter", scope, myCounter);
String s = "";
for (int i=0; i < args.length; i++) {
s += args[i];
}
Object result = cx.evaluateString(scope, s, "<cmd>", 1, null);
System.err.println(Context.toString(result));
} finally {
Context.exit();
}
}
}

View File

@@ -1,39 +1,20 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* License.
* NPL.
*
* The Original Code is Rhino code, released
* May 6, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
import org.mozilla.javascript.*;
import java.io.*;
@@ -46,15 +27,7 @@ import java.io.*;
*
* @author Norris Boyd
*/
public class Shell extends ScriptableObject
{
private static final long serialVersionUID = -5638074146250193112L;
@Override
public String getClassName()
{
return "global";
}
public class Shell extends ScriptableObject {
/**
* Main entry point.
@@ -67,38 +40,42 @@ public class Shell extends ScriptableObject
public static void main(String args[]) {
// Associate a new Context with this thread
Context cx = Context.enter();
// A bit of shorthand: since Shell extends ScriptableObject,
// we can make it the global object.
global = new Shell();
// Initialize the standard objects (Object, Function, etc.)
// This must be done before scripts can be executed.
cx.initStandardObjects(global);
// Define some global functions particular to the shell. Note
// that these functions are not part of ECMA.
String[] names = { "print", "quit", "version", "load", "help" };
try {
// Initialize the standard objects (Object, Function, etc.)
// This must be done before scripts can be executed.
Shell shell = new Shell();
cx.initStandardObjects(shell);
// Define some global functions particular to the shell. Note
// that these functions are not part of ECMA.
String[] names = { "print", "quit", "version", "load", "help" };
shell.defineFunctionProperties(names, Shell.class,
ScriptableObject.DONTENUM);
args = processOptions(cx, args);
// Set up "arguments" in the global scope to contain the command
// line arguments after the name of the script to execute
Object[] array;
if (args.length == 0) {
array = new Object[0];
} else {
int length = args.length - 1;
array = new Object[length];
System.arraycopy(args, 1, array, 0, length);
}
Scriptable argsObj = cx.newArray(shell, array);
shell.defineProperty("arguments", argsObj,
ScriptableObject.DONTENUM);
shell.processSource(cx, args.length == 0 ? null : args[0]);
} finally {
Context.exit();
global.defineFunctionProperties(names, Shell.class,
ScriptableObject.DONTENUM);
} catch (PropertyException e) {
throw new Error(e.getMessage());
}
args = processOptions(cx, args);
// Set up "arguments" in the global scope to contain the command
// line arguments after the name of the script to execute
Object[] array = args;
if (args.length > 0) {
int length = args.length - 1;
array = new Object[length];
System.arraycopy(args, 1, array, 0, length);
}
Scriptable argsObj = cx.newArray(global, array);
global.defineProperty("arguments", argsObj,
ScriptableObject.DONTENUM);
processSource(cx, args.length == 0 ? null : args[0]);
cx.exit();
}
/**
@@ -116,7 +93,7 @@ public class Shell extends ScriptableObject
if (arg.equals("-version")) {
if (++i == args.length)
usage(arg);
double d = Context.toNumber(args[i]);
double d = cx.toNumber(args[i]);
if (d != d)
usage(arg);
cx.setLanguageVersion((int) d);
@@ -127,13 +104,25 @@ public class Shell extends ScriptableObject
return new String[0];
}
/**
* Return name of this class, the global object.
*
* This method must be implemented in all concrete classes
* extending ScriptableObject.
*
* @see com.netscape.javascript.Scriptable#getClassName
*/
public String getClassName() {
return "global";
}
/**
* Print a usage message.
*/
private static void usage(String s) {
public static void usage(String s) {
p("Didn't understand \"" + s + "\".");
p("Valid arguments are:");
p("-version 100|110|120|130|140|150|160|170");
p("-version 100|110|120|130");
System.exit(1);
}
@@ -142,7 +131,7 @@ public class Shell extends ScriptableObject
*
* This method is defined as a JavaScript function.
*/
public void help() {
public static void help(String s) {
p("");
p("Command Description");
p("======= ===========");
@@ -192,8 +181,7 @@ public class Shell extends ScriptableObject
*
* This method is defined as a JavaScript function.
*/
public void quit()
{
public static void quit() {
quitting = true;
}
@@ -205,9 +193,9 @@ public class Shell extends ScriptableObject
public static double version(Context cx, Scriptable thisObj,
Object[] args, Function funObj)
{
double result = cx.getLanguageVersion();
double result = (double) cx.getLanguageVersion();
if (args.length > 0) {
double d = Context.toNumber(args[0]);
double d = cx.toNumber(args[0]);
cx.setLanguageVersion((int) d);
}
return result;
@@ -222,9 +210,8 @@ public class Shell extends ScriptableObject
public static void load(Context cx, Scriptable thisObj,
Object[] args, Function funObj)
{
Shell shell = (Shell)getTopLevelScope(thisObj);
for (int i = 0; i < args.length; i++) {
shell.processSource(cx, Context.toString(args[i]));
for (int i=0; i < args.length; i++) {
processSource(cx, cx.toString(args[i]));
}
}
@@ -236,8 +223,7 @@ public class Shell extends ScriptableObject
* @param filename the name of the file to compile, or null
* for interactive mode.
*/
private void processSource(Context cx, String filename)
{
public static void processSource(Context cx, String filename) {
if (filename == null) {
BufferedReader in = new BufferedReader
(new InputStreamReader(System.in));
@@ -269,11 +255,11 @@ public class Shell extends ScriptableObject
if (cx.stringIsCompilableUnit(source))
break;
}
Object result = cx.evaluateString(this, source,
Object result = cx.evaluateString(global, source,
sourceName, startline,
null);
if (result != Context.getUndefinedValue()) {
System.err.println(Context.toString(result));
if (result != cx.getUndefinedValue()) {
System.err.println(cx.toString(result));
}
}
catch (WrappedException we) {
@@ -313,7 +299,7 @@ public class Shell extends ScriptableObject
// Here we evalute the entire contents of the file as
// a script. Text is printed only if the print() function
// is called.
cx.evaluateReader(this, in, filename, 1, null);
cx.evaluateReader(global, in, filename, 1, null);
}
catch (WrappedException we) {
System.err.println(we.getWrappedException().toString());
@@ -337,12 +323,14 @@ public class Shell extends ScriptableObject
}
}
}
System.gc();
}
private static void p(String s) {
System.out.println(s);
}
private boolean quitting;
static Shell global;
static boolean quitting;
}

View File

@@ -1,111 +0,0 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released May 6, 1999.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* SwingApplication.js - a translation into JavaScript of
* SwingApplication.java, a java.sun.com Swing example.
*
* @author Roger E Critchlow, Jr.
*/
var swingNames = JavaImporter();
swingNames.importPackage(Packages.javax.swing);
swingNames.importPackage(Packages.java.awt);
swingNames.importPackage(Packages.java.awt.event);
function createComponents()
{
with (swingNames) {
var labelPrefix = "Number of button clicks: ";
var numClicks = 0;
var label = new JLabel(labelPrefix + numClicks);
var button = new JButton("I'm a Swing button!");
button.mnemonic = KeyEvent.VK_I;
// Since Rhino 1.5R5 JS functions can be passed to Java method if
// corresponding argument type is Java interface with single method
// or all its methods have the same number of arguments and the
// corresponding arguments has the same type. See also comments for
// frame.addWindowListener bellow
button.addActionListener(function() {
numClicks += 1;
label.setText(labelPrefix + numClicks);
});
label.setLabelFor(button);
/*
* An easy way to put space between a top-level container
* and its contents is to put the contents in a JPanel
* that has an "empty" border.
*/
var pane = new JPanel();
pane.border = BorderFactory.createEmptyBorder(30, //top
30, //left
10, //bottom
30); //right
pane.setLayout(new GridLayout(0, 1));
pane.add(button);
pane.add(label);
return pane;
}
}
with (swingNames) {
try {
UIManager.
setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
} catch (e) { }
//Create the top-level container and add contents to it.
var frame = new swingNames.JFrame("SwingApplication");
frame.getContentPane().add(createComponents(), BorderLayout.CENTER);
// Pass JS function as implementation of WindowListener. It is allowed since
// all methods in WindowListener have the same signature. To distinguish
// between methods Rhino passes to JS function the name of corresponding
// method as the last argument
frame.addWindowListener(function(event, methodName) {
if (methodName == "windowClosing") {
java.lang.System.exit(0);
}
});
//Finish setting up the frame, and show it.
frame.pack();
frame.setVisible(true);
}

View File

@@ -1,47 +1,9 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1999.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Norris Boyd
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
/**
* checkParam.js
*
* The files given as arguments on the command line are assumed to be
* Java source code files. This program checks to see that the @param
* tags in the documentation comments match with the parameters for
* tags in the documentation comments match with the parameters for
* the associated Java methods.
* <p>
* Any errors found are reported.
@@ -57,12 +19,12 @@ function stringEndsWith(str, suffix) {
/**
* Perform processing once the end of a documentation comment is seen.
*
* Look for a parameter list following the end of the comment and
* Look for a parameter list following the end of the comment and
* collect the parameters and compare to the @param entries.
* Report any discrepancies.
* @param f the current file
* @param a an array of parameters from @param comments
* @param line the string containing the comment end (in case the
* @param line the string containing the comment end (in case the
* parameters are on the same line)
*/
function processCommentEnd(f, a, line) {
@@ -75,14 +37,14 @@ function processCommentEnd(f, a, line) {
var m = line.match(/\(([^\)]+)\)/);
var args = m ? m[1].split(",") : [];
if (a.length != args.length) {
print('"' + f.name +
print('"' + f.name +
'"; line ' + f.lineNumber +
' mismatch: had a different number' +
' of @param entries and parameters.');
} else {
for (var i=0; i < a.length; i++) {
if (!stringEndsWith(args[i], a[i])) {
print('"' + f.name +
print('"' + f.name +
'"; line ' + f.lineNumber +
' mismatch: had "' + a[i] +
'" and "' + args[i] + '".');
@@ -91,9 +53,9 @@ function processCommentEnd(f, a, line) {
}
}
}
/**
* Process the given file, looking for mismatched @param lists and
* Process the given file, looking for mismatched @param lists and
* parameter lists.
* @param f the file to process
*/
@@ -107,11 +69,11 @@ function processFile(f) {
if (line.match(/@param/)) {
while (m = line.match(/@param[ ]+([^ ]+)/)) {
a[i++] = m[1];
line = f.readLine();
line = f.readLine();
if (line == null)
break outer;
}
}
}
if (i != 0 && line.match(/\*\//)) {
processCommentEnd(f, a, line);
i = 0;
@@ -119,7 +81,7 @@ function processFile(f) {
}
}
if (i != 0) {
print('"' + f.name +
print('"' + f.name +
'"; line ' + f.lineNumber +
' missing parameters at end of file.');
}

View File

@@ -1,68 +1,34 @@
/* -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1999.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Patrick Beard
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
/*
Implementing the interface java.util.Enumeration passing the object
with JavaScript implementation directly to the constructor.
This is a shorthand for JavaAdapter constructor:
enum.js
Implementing the interface java.util.Enumeration using the new syntax.
Note that this syntax is experimental only, and hasn't been approved
by ECMA.
The same functionality can be had without the new syntax using the
uglier syntax:
elements = new JavaAdapter(java.util.Enumeration, {
index: 0,
elements: array,
hasMoreElements: function ...
nextElement: function ...
var elements = new JavaAdapter(java.util.Enumeration, {
index: 0, elements: array,
hasMoreElements: function ...
nextElement: function ...
});
by Patrick C. Beard.
*/
// an array to enumerate.
var array = [0, 1, 2];
// create an array enumeration.
var elements = new java.util.Enumeration({
index: 0,
elements: array,
hasMoreElements: function() {
return (this.index < this.elements.length);
},
nextElement: function() {
return this.elements[this.index++];
var elements = new java.util.Enumeration() {
index: 0, elements: array,
hasMoreElements: function() {
return (this.index < this.elements.length);
},
nextElement: function() {
return this.elements[this.index++];
}
});
};
// now print out the array by enumerating through the Enumeration
while (elements.hasMoreElements())

View File

@@ -1,49 +1,10 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1999.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Norris Boyd
* Roland Pennings
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
/**
* Process a JavaScript source file and process special comments
* to produce an HTML file of documentation, similar to javadoc.
* @author Norris Boyd
* @see rhinotip.jar
* @lastmodified xx
* @version 1.2 Roland Pennings: Allow multiple files for a function.
* @version 1.2 Roland Pennings: Allow multiple files for a function.
* @version 1.3 Roland Pennings: Removes ../.. from the input directory name
*/
defineClass("File")
@@ -64,7 +25,7 @@ var debug = 0;
/**
* Process JavaScript source file <code>f</code>, writing jsdoc to
* Process JavaScript source file <code>f</code>, writing jsdoc to
* file <code>out</code>.
* @param f input file
* @param fname name of the input file (without the path)
@@ -75,11 +36,11 @@ function processFile(f, fname, inputdir, out) {
var s;
var firstLine = true;
indexFileArray[fname] = "";
// write the header of the output file
out.writeLine('<HTML><HEADER><TITLE>' + fname + '</TITLE><BODY>');
if (inputdir != null) {
outstr = '<a name=\"_top_\"></a><pre><a href=\"' + indexFile + '\">Index Files</a> ';
outstr = '<a name=\"_top_\"></a><pre><a href=\"' + indexFile + '\">Index Files</a> ';
outstr += '<a href=\"' + indexFunction + '\">Index Functions</a></pre><hr>';
out.writeLine(outstr);
}
@@ -101,7 +62,7 @@ function processFile(f, fname, inputdir, out) {
// Strip leading whitespace and "*".
comment += s.replace(/^\s*\*/, "");
s = f.readLine();
} while (s != null);
} while (s != null);
if (debug)
print("Found comment " + comment);
@@ -122,59 +83,31 @@ function processFile(f, fname, inputdir, out) {
m = s.match(/^\s*function\s+((\w+)|(\w+)(\s+))\(([^)]*)\)/);
if (m != null)
{
// Found a function start
var htmlText = processFunction(m[1], m[5], comment); // sjm changed from 2nd to 5th arg
// Found a function start
var htmlText = processFunction(m[1], m[2], comment);
// Save the text in a global variable, so we
// can write out a table of contents first.
functionDocArray[functionDocArray.length] = {name:m[1], text:htmlText};
// Store the function also in the indexFunctionArray
// so we can have a separate file with the function table of contents
if (indexFunctionArray[m[1]]) {
// print("ERROR: function: " + m[1] + " is defined more than once!");
// Allow multiple files for a function
with (indexFunctionArray[m[1]]) {
filename = filename + "|" + fname;
// print("filename = " + filename);
}
}
else {
indexFunctionArray[m[1]] = {filename:fname};
}
//reset comment
comment = "";
}
// match a method being bound to a prototype
m = s.match(/^\s*(\w*)\.prototype\.(\w*)\s*=\s*function\s*\(([^)]*)\)/);
if (m != null)
{
// Found a method being bound to a prototype.
var htmlText = processPrototypeMethod(m[1], m[2], m[3], comment);
// Save the text in a global variable, so we
// can write out a table of contents first.
functionDocArray[functionDocArray.length] = {name:m[1]+".prototype."+m[2], text:htmlText};
// Store the function also in the indexFunctionArray
// so we can have a separate file with the function table of contents
if (indexFunctionArray[m[1]]) {
// print("ERROR: function: " + m[1] + " is defined more than once!");
// Allow multiple files for a function
with (indexFunctionArray[m[1]]) {
filename = filename + "|" + fname;
// print("filename = " + filename);
}
}
else {
indexFunctionArray[m[1]] = {filename:fname};
}
//reset comment
comment = "";
}
firstLine = false;
// Save the text in a global variable, so we
// can write out a table of contents first.
functionDocArray[functionDocArray.length] =
{name:m[1], text:htmlText};
// Store the function also in the indexFunctionArray
// so we can have a seperate file with the function table of contents
if (indexFunctionArray[m[1]]) {
// print("ERROR: function: " + m[1] + " is defined more than once!");
// Allow multiple files for a function
with (indexFunctionArray[m[1]]) {
filename = filename + "|" + fname;
// print("filename = " + filename);
}
} else {
indexFunctionArray[m[1]] =
{filename:fname};
}
//reset comment
comment = "";
}
firstLine = false;
}
// Write table of contents.
@@ -196,7 +129,7 @@ function processFile(f, fname, inputdir, out) {
out.writeLine('</BODY></HTML>');
// Now clean up the doc array
functionDocArray = [];
functionDocArray = [];
}
/**
@@ -217,24 +150,7 @@ function processFunction(name, args, comment) {
"<P><BR><BR>";
}
/**
* Process a method being bound to a prototype.
* @param proto the name of the prototype
* @param name the name of the function
* @param args the args of the function as a single string
* @param comment the text of the comment
* @return a string for the HTML text of the documentation
*/
function processPrototypeMethod(proto, name, args, comment) {
if (debug)
print("Processing " + proto + ".prototype." + name + " " + args + " " + comment);
return "<H2> Method " + proto + ".prototype." + name + "</H2>" +
"<PRE>" +
proto + ".prototype." + name + " = function(" + args + ")" +
"</PRE>" +
processComment(comment,0,name) +
"<P><BR><BR>";
}
/**
@@ -247,11 +163,11 @@ function processPrototypeMethod(proto, name, args, comment) {
function processComment(comment,firstLine,fname) {
var tags = {};
// Use the "lambda" form of regular expression replace,
// where the replacement object is a function rather
// than a string. The function is called with the
// where the replacement object is a function rather
// than a string. The function is called with the
// matched text and any parenthetical matches as
// arguments, and the result of the function used as the
// replacement text.
// replacement text.
// Here we use the function to build up the "tags" object,
// which has a property for each "@" tag that is the name
// of the tag, and whose value is an array of the
@@ -263,9 +179,9 @@ function processComment(comment,firstLine,fname) {
tags[name] = a;
return "";
});
// if we have a comment at the beginning of a file
// store the comment for the index file
// store the comment for the index file
if (firstLine) {
indexFileArray[fname] = comment;
}
@@ -277,7 +193,7 @@ function processComment(comment,firstLine,fname) {
var params = "";
for (var i=0; i < array.length; i++) {
var m = array[i].match(/(\w+)\s+(.*)/);
params += '<TR><TD><I>'+m[1]+'</I></TD>' +
params += '<TR><TD><I>'+m[1]+'</I></TD>' +
'<TD>'+m[2]+'</TD></TR>';
}
out += '<TABLE WIDTH="90%" BORDER=1>';
@@ -329,7 +245,7 @@ function processComment(comment,firstLine,fname) {
out += '<DT><B>Last modified:</B><DD>';
out += '<script><!--\n';
out += 'document.writeln(document.lastModified);\n';
out += '// ---></script>\n';
out += '// ---></script>\n';
out += '</DL><P>';
}
@@ -341,9 +257,9 @@ function processComment(comment,firstLine,fname) {
* Create an html output file
* @param outputdir directory to put the file
* @param htmlfile name of the file
*/
*/
function CreateOutputFile(outputdir,htmlfile)
{
{
if (outputdir==null)
{
var outname = htmlfile;
@@ -358,18 +274,18 @@ function CreateOutputFile(outputdir,htmlfile)
}
/**
* Process a javascript file. Puts the generated HTML file in the outdir
* Process a javascript file. Puts the generated HTML file in the outdir
* @param filename name of the javascript file
* @inputdir input directory of the file (default null)
*/
function processJSFile(filename,inputdir)
function processJSFile(filename,inputdir)
{
if (debug) print("filename = " + filename + " inputdir = " + inputdir);
if (!filename.match(/\.js$/)) {
print("Expected filename to end in '.js'; had instead " +
if (!filename.match(/\.js$/)) {
print("Expected filename to end in '.js'; had instead " +
filename + ". I don't treat the file.");
} else {
} else {
if (inputdir==null)
{
var inname = filename;
@@ -382,12 +298,12 @@ function processJSFile(filename,inputdir)
print("Processing file " + inname);
var f = new File(inname);
// create the output file
var htmlfile = filename.replace(/\.js$/, ".html");
var out = CreateOutputFile(outputdir,htmlfile);
processFile(f, filename, inputdir, out);
out.close();
}
@@ -401,7 +317,7 @@ function GenerateIndex(dirname)
{
// construct the files index file
var out = CreateOutputFile(outputdir,indexFile);
// write the beginning of the file
out.writeLine('<HTML><HEADER><TITLE>File Index - directory: ' + dirname + '</TITLE><BODY>');
out.writeLine('<H1>File Index - directory: ' + dirname + '</H1>\n');
@@ -415,7 +331,7 @@ function GenerateIndex(dirname)
// sort the index file array
var SortedFileArray = [];
for (var fname in indexFileArray)
SortedFileArray.push(fname);
SortedFileArray.push(fname);
SortedFileArray.sort();
for (var i=0; i < SortedFileArray.length; i++) {
@@ -430,10 +346,10 @@ function GenerateIndex(dirname)
}
out.writeLine('</TABLE></BODY></HTML>');
out.close();
// construct the functions index file
var out = CreateOutputFile(outputdir,indexFunction);
// write the beginning of the file
out.writeLine('<HTML><HEADER><TITLE>Function Index - directory: ' + dirname + '</TITLE><BODY>');
out.writeLine('<H1>Function Index - directory: ' + dirname + '</H1>\n');
@@ -441,11 +357,11 @@ function GenerateIndex(dirname)
out.writeLine('<TR BGCOLOR=0xdddddddd>');
out.writeLine('<TD><B>Function</B></TD>');
out.writeLine('<TD><B>Files</B></TD></TR>');
// sort the function array
var SortedFunctionArray = [];
for (var functionname in indexFunctionArray)
SortedFunctionArray.push(functionname);
SortedFunctionArray.push(functionname);
SortedFunctionArray.sort();
for (var j=0; j < SortedFunctionArray.length; j++) {
@@ -479,10 +395,10 @@ function PrintOptions()
// Main Script
// first read the arguments
// first read the arguments
if (! arguments)
PrintOptions();
for (var i=0; i < arguments.length; i++) {
if (debug) print("argument: + \'" + arguments[i] + "\'");
if (arguments[i].match(/^\-/)) {
@@ -492,7 +408,7 @@ for (var i=0; i < arguments.length; i++) {
outputdir = String(arguments[i+1]);
if (debug) print("outputdir: + \'" + outputdir + "\'");
i++;
i++;
}
else if (String(arguments[i])=="-i"){
// process all files in an input directory
@@ -513,16 +429,16 @@ if (debug) print("inputdir: + \'" + arguments[i+1] + "\'");
FileList.push(String(arguments[i]));
}
}
}
// first handle the single files
for (var i in FileList)
for (var i in FileList)
processJSFile(FileList[i],null);
// then handle the input directories
for (var j in DirList) {
var inputdir = String(DirList[j]);
print("Process input directory: " + inputdir);
// clean up index arrays
@@ -531,13 +447,13 @@ for (var j in DirList) {
// for the directory name get rid of ../../ or ..\..\
inputDirName = inputdir.replace(/\.\.\/|\.\.\\/g,"");
indexFile = indexFileName + "_" + inputDirName + ".html";
indexFunction = indexFunctionName + "_" + inputDirName + ".html";
print("indexFile = " + indexFile);
print("indexFunction = " + indexFunction);
// read the files in the directory
var DirFile = new java.io.File(inputdir);
var lst = DirFile.list();
@@ -546,7 +462,7 @@ print("indexFunction = " + indexFunction);
for (var i=0; i < lst.length; i++)
{
processJSFile(String(lst[i]),inputdir);
}
}
// generate the index files for the input directory
GenerateIndex(inputDirName);

View File

@@ -1,47 +1,9 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1999.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Norris Boyd
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
/**
* liveConnect.js: a simple demonstration of JavaScript-to-Java connectivity
*/
// Create a new StringBuffer. Note that the class name must be fully qualified
// by its package. Packages other than "java" must start with "Packages", i.e.,
// by its package. Packages other than "java" must start with "Packages", i.e.,
// "Packages.javax.servlet...".
var sb = new java.lang.StringBuffer();
@@ -54,4 +16,4 @@ sb.append(true);
// Now print it out. (The toString() method of sb is automatically called
// to convert the buffer to a string.)
// Should print "hi, mom3.0true".
print(sb);
print(sb);

View File

@@ -1,46 +1,8 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1999.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Norris Boyd
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */
// unique.js: read the contents of a file and print out the unique lines
defineClass("File")
// "arguments[0]" refers to the first argument at the command line to the
// "arguments[0]" refers to the first argument at the command line to the
// script, if present. If not present, "arguments[0]" will be undefined,
// which will cause f to read from System.in.
var f = new File(arguments[0]);
@@ -53,4 +15,4 @@ while ((line = f.readLine()) != null) {
}
for (i in o) {
print(i);
}
}

Binary file not shown.

View File

@@ -1,3 +1,2 @@
Manifest-Version: 1.0
Main-Class: org.mozilla.javascript.tools.shell.Main
Class-Path: xbean.jar

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,112 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
package org.mozilla.javascript;
/**
* This class implements the "arguments" object.
*
* See ECMA 10.1.8
*
* @see org.mozilla.javascript.NativeCall
* @author Norris Boyd
*/
class Arguments extends ScriptableObject {
public Arguments(NativeCall activation) {
this.activation = activation;
Scriptable parent = activation.getParentScope();
setParentScope(parent);
setPrototype(ScriptableObject.getObjectPrototype(parent));
args = activation.getOriginalArguments();
int length = args.length;
Object callee = activation.funObj;
defineProperty("length", new Integer(length),
ScriptableObject.DONTENUM);
defineProperty("callee", callee, ScriptableObject.DONTENUM);
hasCaller = activation.funObj.version <= Context.VERSION_1_3;
}
public String getClassName() {
return "Arguments";
}
public boolean has(String name, Scriptable start) {
return (hasCaller && name.equals("caller")) || super.has(name, start);
}
public boolean has(int index, Scriptable start) {
Object[] args = activation.getOriginalArguments();
return (0 <= index && index < args.length) || super.has(index, start);
}
public Object get(String name, Scriptable start) {
if (hasCaller && name.equals("caller")) {
NativeCall caller = activation.caller;
if (caller == null || caller.originalArgs == null)
return null;
return caller.get("arguments", caller);
}
return super.get(name, start);
}
public Object get(int index, Scriptable start) {
if (0 <= index && index < args.length) {
NativeFunction f = activation.funObj;
if (index < f.argCount)
return activation.get(f.names[index+1], activation);
return args[index];
}
return super.get(index, start);
}
public void put(String name, Scriptable start, Object value) {
if (name.equals("caller")) {
// Set "hasCaller" to false so that we won't look up a
// computed value.
hasCaller = false;
}
super.put(name, start, value);
}
public void put(int index, Scriptable start, Object value) {
if (0 <= index && index < args.length) {
NativeFunction f = activation.funObj;
if (index < f.argCount)
activation.put(f.names[index+1], activation, value);
else
args[index] = value;
return;
}
super.put(index, start, value);
}
public void delete(String name) {
if (name.equals("caller"))
hasCaller = false;
super.delete(name);
}
private NativeCall activation;
private Object[] args;
private boolean hasCaller;
}

View File

@@ -0,0 +1,58 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
package org.mozilla.javascript;
final class BinaryDigitReader {
int lgBase; // Logarithm of base of number
int digit; // Current digit value in radix given by base
int digitPos; // Bit position of last bit extracted from digit
String digits; // String containing the digits
int start; // Index of the first remaining digit
int end; // Index past the last remaining digit
BinaryDigitReader(int base, String digits, int start, int end) {
lgBase = 0;
while (base != 1) {
lgBase++;
base >>= 1;
}
digitPos = 0;
this.digits = digits;
this.start = start;
this.end = end;
}
/* Return the next binary digit from the number or -1 if done */
int getNextBinaryDigit()
{
if (digitPos == 0) {
if (start == end)
return -1;
char c = digits.charAt(start++);
if ('0' <= c && c <= '9')
digit = c - '0';
else if ('a' <= c && c <= 'z')
digit = c - 'a' + 10;
else digit = c - 'A' + 10;
digitPos = lgBase;
}
return digit >> --digitPos & 1;
}
}

View File

@@ -0,0 +1,32 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
// API class
package org.mozilla.javascript;
/**
* Thrown if errors are detected while attempting to define a host object
* from a Java class.
*/
public class ClassDefinitionException extends Exception {
public ClassDefinitionException(String detail) {
super(detail);
}
}

View File

@@ -0,0 +1,38 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
package org.mozilla.javascript;
public interface ClassNameHelper {
public String getTargetClassFileName();
public void setTargetClassFileName(String classFileName);
public String getTargetPackage();
public void setTargetPackage(String targetPackage);
public String getTargetClassFileName(String className);
public String getGeneratingDirectory();
public void setTargetExtends(Class extendsClass);
public void setTargetImplements(Class[] implementsClasses);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,75 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
package org.mozilla.javascript;
/**
* This interface supports low-level per statement debug hooks
* <p>
* This interface can be implemented and used to do statement level
* interrupting and trapping of executing scripts.
* org.mozilla.javascript.debug.IDebugManager uses this system and provides
* a higher level abstraction more appropriate as a debugger API.
*
* @see org.mozilla.javascript.Context#setBytecodeHook
* @see org.mozilla.javascript.debug.IDebugManager
* @author John Bandhauer
*/
public interface DeepBytecodeHook
{
/**
* Possible hook return values.
*/
/**
* The executing script should continue.
*/
public static final int CONTINUE = 0;
/**
* The executing script should throw the object passed back in
* retVal[0]. This must be an object derived from java.lang.Throwable.
*/
public static final int THROW = 1;
/**
* The executing script should immediately return the object passed
* back in retVal[0].
*/
public static final int RETURN_VALUE = 2;
/**
* Handle trap.
*
* @param cx current context
* @param pc current program counter
* @param retVal single Object array to hold return value or exception
* @return one of {CONTINUE | THROW | RETURN_VALUE}
*/
public int trapped(Context cx, int pc, Object[] retVal);
/**
* Handle interrupt.
*
* @param cx current context
* @param pc current program counter
* @param retVal single Object array to hold return value or exception
* @return one of {CONTINUE | THROW | RETURN_VALUE}
*/
public int interrupted(Context cx, int pc, Object[] retVal);
}

View File

@@ -0,0 +1,59 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
package org.mozilla.javascript;
/**
* This interface supports low-level call debug hooks
* <p>
* This interface can be implemented and used to hook JavaScript
* function calls. org.mozilla.javascript.debug.IDebugManager uses this
* system and provides a higher level abstraction more appropriate
* as a debugger API.
*
* @see org.mozilla.javascript.Context#setCallHook
* @see org.mozilla.javascript.debug.IDebugManager
* @author John Bandhauer
*/
public interface DeepCallHook
{
/**
* Notification that a function is about to be called.
*
* @param cx current context
* @param fun function to be called
* @param thisArg the 'this' of the object
* @param args constructor arguments array
* @return arbitrary object which is subsequently passed to postCall
* @see org.mozilla.javascript.debug.NativeDelegate#callDebug
*/
public Object preCall(Context cx, Object fun, Object thisArg, Object[] args);
/**
* Notification that a call returned.
*
* @param cx current context
* @param ref value returned from previous call to preCall
* @param retVal value returned by the callee (null if exception thrown)
* @param e exception thrown by callee (null if none thrown)
* @see org.mozilla.javascript.debug.NativeDelegate#callDebug
*/
public void postCall(Context cx, Object ref, Object retVal,
JavaScriptException e);
}

View File

@@ -0,0 +1,53 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
package org.mozilla.javascript;
/**
* This interface supports low-level error reporter hooks.
* <p>
* This interface can be implemented and used to hook calls to the
* error reporter. org.mozilla.javascript.debug.IDebugManager uses this
* system and provides a higher level abstraction more appropriate
* as a debugger API.
*
* @see org.mozilla.javascript.Context#setErrorReporterHook
* @see org.mozilla.javascript.debug.IDebugManager
* @author John Bandhauer
*/
public interface DeepErrorReporterHook extends ErrorReporter
{
/**
* Change the current error reporter.
*
* @return the previous error reporter
* @see org.mozilla.javascript.ErrorReporter
* @see org.mozilla.javascript.Context#setErrorReporter
*/
public ErrorReporter setErrorReporter(ErrorReporter reporter);
/**
* Get the current error reporter.
*
* @see org.mozilla.javascript.ErrorReporter
* @see org.mozilla.javascript.Context#getErrorReporter
*/
public ErrorReporter getErrorReporter();
}

View File

@@ -0,0 +1,58 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
package org.mozilla.javascript;
/**
* This interface supports low-level execute debug hooks.
* <p>
* This interface can be implemented and used to hook JavaScript
* script execution. org.mozilla.javascript.debug.IDebugManager uses this
* system and provides a higher level abstraction more appropriate
* as a debugger API.
*
* @see org.mozilla.javascript.Context#setExecuteHook
* @see org.mozilla.javascript.debug.IDebugManager
* @author John Bandhauer
*/
public interface DeepExecuteHook
{
/**
* Notification that a top-level script is about to be executed.
*
* @param cx current context
* @param fun script
* @param scope scope
* @return arbitrary object which is subsequently passed to postExecute
* @see org.mozilla.javascript.debug.NativeDelegate#executeDebug
*/
public Object preExecute(Context cx, NativeFunction fun, Scriptable scope);
/**
* Notification that a top-level script execution returned.
*
* @param cx current context
* @param ref value returned from previous call to preExecute
* @param retVal value returned by the script (null if exception thrown)
* @param e exception thrown by script (null if none thrown)
* @see org.mozilla.javascript.debug.NativeDelegate#executeDebug
*/
public void postExecute(Context cx, Object ref, Object retVal,
JavaScriptException e);
}

View File

@@ -0,0 +1,59 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
package org.mozilla.javascript;
/**
* This interface supports low-level new object debug hooks.
* <p>
* This interface can be implemented and used to hook JavaScript
* object creation; i.e. calls for JavaScript constructor
* functions. org.mozilla.javascript.debug.IDebugManager uses this
* system and provides a higher level abstraction more appropriate
* as a debugger API.
*
* @see org.mozilla.javascript.Context#setNewObjectHook
* @see org.mozilla.javascript.debug.IDebugManager
* @author John Bandhauer
*/
public interface DeepNewObjectHook
{
/**
* Notification that a constructor is about to be called.
*
* @param cx current context
* @param fun constructor function
* @param args constructor arguments array
* @return arbitrary object which is subsequently passed to postNewObject
* @see org.mozilla.javascript.debug.NativeDelegate#newObjectDebug
*/
public Object preNewObject(Context cx, Object fun, Object[] args);
/**
* Notification that a constructor returned.
*
* @param cx current context
* @param ref value returned from previous call to preNewObject
* @param retVal value returned by the constructor (null if exception thrown)
* @param e exception thrown by constructor (null if none thrown)
* @see org.mozilla.javascript.debug.NativeDelegate#newObjectDebug
*/
public void postNewObject(Context cx, Object ref, Scriptable retVal,
Exception e);
}

View File

@@ -0,0 +1,57 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
package org.mozilla.javascript;
/**
* This interface supports low-level script load/unload debug hooks.
* <p>
* This interface can be implemented and used to hook script loading
* and unloading. org.mozilla.javascript.debug.IDebugManager uses this
* system and provides a higher level abstraction more appropriate
* as a debugger API.
*
* @see org.mozilla.javascript.Context#setScriptHook
* @see org.mozilla.javascript.debug.IDebugManager
* @author John Bandhauer
*/
public interface DeepScriptHook
{
/**
* Notification that a script is being loaded.
*
* @param cx current context
* @param obj script or function being loaded
*/
public void loadingScript(Context cx, NativeFunction obj);
/**
* Notification that a script is being unloaded.
* <p>
* NOTE: this currently happens as part of the Java garbage
* collection process; i.e. it is called by the finalize method
* of the script and is thus likely to be called on a system
* thread. Also, this is thus not likely to be called if there are
* any outstanding references to the script.
*
* @param cx context which originally loaded the script
* @param obj script or function being unloaded
*/
public void unloadingScript(Context cx, NativeFunction obj);
}

View File

@@ -0,0 +1,46 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
package org.mozilla.javascript;
/**
* This is the default error reporter for JavaScript.
*
* @author Norris Boyd
*/
class DefaultErrorReporter implements ErrorReporter {
public void warning(String message, String sourceName, int line,
String lineSource, int lineOffset)
{
// do nothing
}
public void error(String message, String sourceName, int line,
String lineSource, int lineOffset)
{
throw new EvaluatorException(message);
}
public EvaluatorException runtimeError(String message, String sourceName,
int line, String lineSource,
int lineOffset)
{
return new EvaluatorException(message);
}
}

View File

@@ -0,0 +1,86 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
// API class
package org.mozilla.javascript;
/**
* This is interface defines a protocol for the reporting of
* errors during JavaScript translation or execution.
*
* @author Norris Boyd
*/
public interface ErrorReporter {
/**
* Report a warning.
*
* The implementing class may choose to ignore the warning
* if it desires.
*
* @param message a String describing the warning
* @param sourceName a String describing the JavaScript source
* where the warning occured; typically a filename or URL
* @param line the line number associated with the warning
* @param lineSource the text of the line (may be null)
* @param lineOffset the offset into lineSource where problem was detected
*/
void warning(String message, String sourceName, int line,
String lineSource, int lineOffset);
/**
* Report an error.
*
* The implementing class is free to throw an exception if
* it desires.
*
* If execution has not yet begun, the JavaScript engine is
* free to find additional errors rather than terminating
* the translation. It will not execute a script that had
* errors, however.
*
* @param message a String describing the error
* @param sourceName a String describing the JavaScript source
* where the error occured; typically a filename or URL
* @param line the line number associated with the error
* @param lineSource the text of the line (may be null)
* @param lineOffset the offset into lineSource where problem was detected
*/
void error(String message, String sourceName, int line,
String lineSource, int lineOffset);
/**
* Creates an EvaluatorException that may be thrown.
*
* runtimeErrors, unlike errors, will always terminate the
* current script.
*
* @param message a String describing the error
* @param sourceName a String describing the JavaScript source
* where the error occured; typically a filename or URL
* @param line the line number associated with the error
* @param lineSource the text of the line (may be null)
* @param lineOffset the offset into lineSource where problem was detected
* @return an EvaluatorException that will be thrown.
*/
EvaluatorException runtimeError(String message, String sourceName,
int line, String lineSource,
int lineOffset);
}

View File

@@ -0,0 +1,38 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
package org.mozilla.javascript;
/**
* The class of exceptions thrown by the JavaScript engine.
*/
public class EvaluatorException extends RuntimeException {
/**
* Create an exception with the specified detail message.
*
* Errors internal to the JavaScript engine will simply throw a
* RuntimeException.
*
* @param detail a message with detail about the exception
*/
public EvaluatorException(String detail) {
super(detail);
}
}

View File

@@ -0,0 +1,322 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
// API class
package org.mozilla.javascript;
import java.util.Hashtable;
import java.util.Enumeration;
/**
* Manipulate a Scriptable object as if its prototype chain were flattened.
* <p>
* Compared to the Scriptable interface, FlattenedObject provides a view of
* Scriptable objects that is easier to use and more closely matches a script
* writer's view of a JavaScript object. <p>
*
* A FlattenedObject is "flattened" in the sense that multiple objects in a
* prototype chain appear to have their properties all appear in the
* FlattenedObject. <p>
*
* Another convenience provided by Flattened object is the ability to access
* properties by a single java.lang.Object id. This id is then converted into
* a String or an int before methods of the Scriptable object are called.
*
* @see org.mozilla.javascript.Scriptable
*
* @author Norris Boyd
*/
public class FlattenedObject {
/**
* Construct a new FlattenedObject.
*
* @param object the object to be viewed with flattened properties
*/
public FlattenedObject(Scriptable object) {
this.obj = object;
}
/**
* Get the associated Scriptable object.
*/
public Scriptable getObject() {
return obj;
}
/**
* Determine if a property exists in an object.
*
* This is a more convenient (and less efficient) form than
* <code>Scriptable.has()</code>.
* It returns true if and only if the property
* exists in this object or any of the objects in its prototype
* chain.
*
* @param id the property index, which may be either a String or a
* Number
* @return true if and only if the property exists in the prototype
* chain
* @see org.mozilla.javascript.Scriptable#has
*/
public boolean hasProperty(Object id) {
String stringId = ScriptRuntime.toString(id);
String s = ScriptRuntime.getStringId(stringId);
if (s == null)
return getBase(obj, ScriptRuntime.getIntId(stringId)) != null;
return getBase(obj, s) != null;
}
/**
* Get a property of an object.
* <p>
* This is a more convenient (and less efficient) form than
* <code>Scriptable.get()</code>. It corresponds exactly to the
* expression <code>obj[id]</code> in JavaScript. This method
* will traverse the prototype chain of an object to find the
* property.<p>
*
* If the property does not exist in the object or its prototype
* chain, the undefined value will be returned.
*
* @param id the property index; can be a String or a Number; the
* String may contain characters representing a number
* @return the value of the property or the undefined value
* @see org.mozilla.javascript.Scriptable#get
* @see org.mozilla.javascript.Context#getUndefinedValue
*/
public Object getProperty(Object id) {
String s = ScriptRuntime.getStringId(id);
int index = s == null ? ScriptRuntime.getIntId(id) : 0;
Scriptable m = obj;
Object result;
for(;;) {
result = s == null ? m.get(index, obj) : m.get(s, obj);
if (result != Scriptable.NOT_FOUND)
break;
m = m.getPrototype();
if (m == null)
return Undefined.instance;
}
if (result instanceof Scriptable)
return new FlattenedObject((Scriptable) result);
return result;
}
/**
* Set a property of an object.
*
* This is a more convenient (and less efficient) form than that
* provided in Scriptable. It corresponds exactly to the
* expression <code>obj[id] = val</code> in JavaScript.<p>
*
* @param id the property index, which may be either a String or
* a Number
* @param value the value of the property
* @see org.mozilla.javascript.Scriptable#put
*/
public void putProperty(Object id, Object value) {
String s = ScriptRuntime.getStringId(id);
if (value instanceof FlattenedObject)
value = ((FlattenedObject) value).getObject();
Scriptable x;
if (s == null) {
int index = ScriptRuntime.getIntId(id);
x = getBase(obj, index);
if (x == null)
x = obj;
x.put(index, obj, value);
return;
}
x = getBase(obj, s);
if (x == null)
x = obj;
x.put(s, obj, value);
}
/**
* Remove a property.
*
* This method provides the functionality of the <code>delete</code>
* operator in JavaScript.
*
* @param id the property index, which may be either a String or
* a Number
* @return true if the property didn't exist, or existed and was removed
* @see org.mozilla.javascript.Scriptable#delete
*/
public boolean deleteProperty(Object id) {
String s = ScriptRuntime.getStringId(id);
if (s == null) {
int index = ScriptRuntime.getIntId(id);
Scriptable base = getBase(obj, index);
if (base == null)
return true;
base.delete(index);
return !base.has(index, base);
}
Scriptable base = getBase(obj, s);
if (base == null)
return true;
base.delete(s);
return !base.has(s, base);
}
/**
* Return an array that contains the ids of the properties.
*
* <p>This method will walk the prototype chain and collect the
* ids of all objects in the prototype chain.<p>
*
* If an id appears in more than one object in the prototype chain,
* it will only be in the array once. (So all the entries in the
* array will be unique respective to equals().)
*
* @see org.mozilla.javascript.Scriptable#getIds
*/
public Object[] getIds() {
Hashtable h = new Hashtable(11);
Scriptable m = obj;
while (m != null) {
Object[] e = m.getIds();
for (int i=0; i < e.length; i++) {
h.put(e[i], Boolean.TRUE);
}
m = m.getPrototype();
}
Enumeration keys = h.keys();
Object elem;
Object[] result = new Object[h.size()];
int index = 0;
while (keys.hasMoreElements()) {
elem = keys.nextElement();
result[index++] = elem;
}
return result;
}
/**
* Consider this object to be a function, and call it.
*
* @param cx the current Context for this thread
* @param thisObj the JavaScript 'this' for the call
* @param args the arguments for the call
* @return the result of the JavaScript function call
* @exception NotAFunctionException if this object is not a function
* @exception JavaScriptException if an uncaught JavaScript exception
* occurred while executing the function
* @see org.mozilla.javascript.Function#call
*/
public Object call(Context cx, Scriptable thisObj, Object[] args)
throws NotAFunctionException,
JavaScriptException
{
if (!(obj instanceof Function)) {
throw new NotAFunctionException();
}
return ScriptRuntime.call(cx, obj, thisObj, args);
}
/**
* Consider this object to be a function, and invoke it as a
* constructor call.
*
* @param cx the current Context for this thread
* @param args the arguments for the constructor call
* @return the allocated object
* @exception NotAFunctionException if this object is not a function
* @exception JavaScriptException if an uncaught JavaScript exception
* occurred while executing the constructor
* @see org.mozilla.javascript.Function#construct
*/
public Scriptable construct(Context cx, Object[] args)
throws NotAFunctionException,
JavaScriptException
{
if (!(obj instanceof Function)) {
throw new NotAFunctionException();
}
return ScriptRuntime.newObject(cx, obj, args, null);
}
/**
* Get the property indicated by the id, and invoke it with the
* specified arguments.
* <p>
* For example, for a FlattenedObject <code>obj</code>,
* and a Java array <code>a</code> consisting of a single string
* <code>"hi"</code>, the call <pre>
* obj.callMethod("m", a)</pre>
* is equivalent to the JavaScript code <code>obj.m("hi")</code>.<p>
*
* If the property is not found or is not a function, an
* exception will be thrown.
*
* @param id the Number or String to use to find the function property
* to call
* @param args the arguments for the constructor call
* @return the result of the call
* @exception PropertyException if the designated property
* was not found
* @exception NotAFunctionException if this object is not a function
* @exception JavaScriptException if an uncaught JavaScript exception
* occurred while executing the method
* @see org.mozilla.javascript.Function#call
*/
public Object callMethod(Object id, Object[] args)
throws PropertyException,
NotAFunctionException,
JavaScriptException
{
if (!hasProperty(id)) {
throw new PropertyException(
Context.getMessage("msg.prop.not.found", null));
}
Object o = getProperty(id);
if (o instanceof FlattenedObject)
return ((FlattenedObject) o).call(Context.getContext(), obj, args);
throw new NotAFunctionException();
}
/****** End of API *******/
private static Scriptable getBase(Scriptable obj, String s) {
Scriptable m = obj;
while (m != null) {
if (m.has(s, obj))
return m;
m = m.getPrototype();
}
return null;
}
private static Scriptable getBase(Scriptable obj, int index) {
Scriptable m = obj;
while (m != null) {
if (m.has(index, obj))
return m;
m = m.getPrototype();
}
return null;
}
private Scriptable obj;
}

View File

@@ -0,0 +1,69 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
// API class
package org.mozilla.javascript;
/**
* This is interface that all functions in JavaScript must implement.
* The interface provides for calling functions and constructors.
*
* @see org.mozilla.javascript.Scriptable
* @author Norris Boyd
*/
public interface Function extends Scriptable {
/**
* Call the function.
*
* Note that the array of arguments is not guaranteed to have
* length greater than 0.
*
* @param cx the current Context for this thread
* @param scope the scope to execute the function relative to. This
* set to the value returned by getParentScope() except
* when the function is called from a closure.
* @param thisObj the JavaScript <code>this</code> object
* @param args the array of arguments
* @return the result of the call
* @exception JavaScriptException if an uncaught exception
* occurred while executing the function
*/
public Object call(Context cx, Scriptable scope, Scriptable thisObj,
Object[] args)
throws JavaScriptException;
/**
* Call the function as a constructor.
*
* This method is invoked by the runtime in order to satisfy a use
* of the JavaScript <code>new</code> operator. This method is
* expected to create a new object and return it.
*
* @param cx the current Context for this thread
* @param scope an enclosing scope of the caller except
* when the function is called from a closure.
* @param args the array of arguments
* @return the allocated object
* @exception JavaScriptException if an uncaught exception
* occurred while executing the constructor
*/
public Scriptable construct(Context cx, Scriptable scope, Object[] args)
throws JavaScriptException;
}

View File

@@ -0,0 +1,48 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
package org.mozilla.javascript;
import java.util.*;
public class FunctionNode extends Node {
public FunctionNode(String name, Node left, Node right) {
super(TokenStream.FUNCTION, left, right, name);
itsVariableTable = new VariableTable();
}
public String getFunctionName() {
return getString();
}
public VariableTable getVariableTable() {
return itsVariableTable;
}
public boolean requiresActivation() {
return itsNeedsActivation;
}
public boolean setRequiresActivation(boolean b) {
return itsNeedsActivation = b;
}
protected VariableTable itsVariableTable;
protected boolean itsNeedsActivation;
}

View File

@@ -0,0 +1,527 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
// API class
package org.mozilla.javascript;
import java.util.Hashtable;
import java.util.Vector;
import java.lang.reflect.*;
public class FunctionObject extends NativeFunction {
/**
* Create a JavaScript function object from a Java method.
*
* <p>The <code>member</code> argument must be either a java.lang.reflect.Method
* or a java.lang.reflect.Constructor and must match one of two forms.<p>
*
* The first form is a member with zero or more parameters
* of the following types: Object, String, boolean, Scriptable,
* byte, short, int, long, float, or double. If the member is
* a Method, the return value must be void or one of the types
* allowed for parameters.<p>
*
* The runtime will perform appropriate conversions based
* upon the type of the parameter. A parameter type of
* Object specifies that no conversions are to be done. A parameter
* of type String will use Context.toString to convert arguments.
* Similarly, parameters of type double, boolean, and Scriptable
* will cause Context.toNumber, Context.toBoolean, and
* Context.toObject, respectively, to be called.<p>
*
* If the method is not static, the Java 'this' value will
* correspond to the JavaScript 'this' value. Any attempt
* to call the function with a 'this' value that is not
* of the right Java type will result in an error.<p>
*
* The second form is the variable arguments (or "varargs")
* form. If the FunctionObject will be used as a constructor,
* the member must have the following parameters
* <pre>
* (Context cx, Object[] args, Function ctorObj,
* boolean inNewExpr)</pre>
* and if it is a Method, be static and return an Object result.<p>
*
* Otherwise, if the FunctionObject will <i>not</i> be used to define a
* constructor, the member must be a static Method with parameters
* (Context cx, Scriptable thisObj, Object[] args,
* Function funObj) </pre>
* <pre>
* and an Object result.<p>
*
* When the function varargs form is called as part of a function call,
* the <code>args</code> parameter contains the
* arguments, with <code>thisObj</code>
* set to the JavaScript 'this' value. <code>funObj</code>
* is the function object for the invoked function.<p>
*
* When the constructor varargs form is called or invoked while evaluating
* a <code>new</code> expression, <code>args</code> contains the
* arguments, <code>ctorObj</code> refers to this FunctionObject, and
* <code>inNewExpr</code> is true if and only if a <code>new</code>
* expression caused the call. This supports defining a function that
* has different behavior when called as a constructor than when
* invoked as a normal function call. (For example, the Boolean
* constructor, when called as a function,
* will convert to boolean rather than creating a new object.)<p>
*
* @param name the name of the function
* @param methodOrConstructor a java.lang.reflect.Method or a java.lang.reflect.Constructor
* that defines the object
* @param scope enclosing scope of function
* @see org.mozilla.javascript.Scriptable
*/
public FunctionObject(String name, Member methodOrConstructor,
Scriptable scope)
{
String methodName;
if (methodOrConstructor instanceof Constructor) {
ctor = (Constructor) methodOrConstructor;
isStatic = true; // well, doesn't take a 'this'
types = ctor.getParameterTypes();
methodName = ctor.getName();
} else {
method = (Method) methodOrConstructor;
isStatic = Modifier.isStatic(method.getModifiers());
types = method.getParameterTypes();
methodName = method.getName();
}
String myNames[] = { name };
super.names = myNames;
int length;
if (types.length == 4 && (types[1].isArray() || types[2].isArray())) {
// Either variable args or an error.
if (types[1].isArray()) {
if (!isStatic ||
types[0] != Context.class ||
types[1].getComponentType() != ScriptRuntime.ObjectClass ||
types[2] != ScriptRuntime.FunctionClass ||
types[3] != Boolean.TYPE)
{
String[] args = { methodName };
String message = Context.getMessage("msg.varargs.ctor",
args);
throw Context.reportRuntimeError(message);
}
parmsLength = VARARGS_CTOR;
} else {
if (!isStatic ||
types[0] != Context.class ||
types[1] != ScriptRuntime.ScriptableClass ||
types[2].getComponentType() != ScriptRuntime.ObjectClass ||
types[3] != ScriptRuntime.FunctionClass)
{
String[] args = { methodName };
String message = Context.getMessage("msg.varargs.fun",
args);
throw Context.reportRuntimeError(message);
}
parmsLength = VARARGS_METHOD;
}
// XXX check return type
length = 1;
} else {
parmsLength = (short) types.length;
boolean hasConversions = false;
for (int i=0; i < parmsLength; i++) {
Class type = types[i];
if (type == ScriptRuntime.ObjectClass) {
// may not need conversions
} else if (type == ScriptRuntime.StringClass ||
type == ScriptRuntime.BooleanClass ||
ScriptRuntime.NumberClass.isAssignableFrom(type) ||
Scriptable.class.isAssignableFrom(type))
{
hasConversions = true;
} else if (type == Boolean.TYPE) {
hasConversions = true;
types[i] = ScriptRuntime.BooleanClass;
} else if (type == Byte.TYPE) {
hasConversions = true;
types[i] = ScriptRuntime.ByteClass;
} else if (type == Short.TYPE) {
hasConversions = true;
types[i] = ScriptRuntime.ShortClass;
} else if (type == Integer.TYPE) {
hasConversions = true;
types[i] = ScriptRuntime.IntegerClass;
} else if (type == Float.TYPE) {
hasConversions = true;
types[i] = ScriptRuntime.FloatClass;
} else if (type == Double.TYPE) {
hasConversions = true;
types[i] = ScriptRuntime.DoubleClass;
} else {
Object[] errArgs = { methodName };
throw Context.reportRuntimeError(
Context.getMessage("msg.bad.parms", errArgs));
}
}
if (!hasConversions)
types = null;
length = parmsLength;
}
// Initialize length property
lengthPropertyValue = (short) length;
hasVoidReturn = method != null && method.getReturnType() == Void.TYPE;
this.argCount = (short) length;
setParentScope(scope);
setPrototype(getFunctionPrototype(scope));
}
/**
* Override ScriptableObject's has, get, and set in order to define
* the "length" property of the function. <p>
*
* We could also have defined the property using ScriptableObject's
* defineProperty method, but that would have consumed a slot in every
* FunctionObject. Most FunctionObjects typically don't have any
* properties anyway, so having the "length" property would cause us
* to allocate an array of slots. <p>
*
* In particular, this method will return true for
* <code>name.equals("length")</code>
* and will delegate to the superclass for all other
* values of <code>name</code>.
*/
public boolean has(String name, Scriptable start) {
return name.equals("length") || super.has(name, start);
}
/**
* Override ScriptableObject's has, get, and set in order to define
* the "length" property of the function. <p>
*
* In particular, this method will return the value defined by
* the method used to construct the object (number of parameters
* of the method, or 1 if the method is a "varargs" form), unless
* setLength has been called with a new value.
*
* @see org.mozilla.javascript.FunctionObject#setLength
*/
public Object get(String name, Scriptable start) {
if (name.equals("length"))
return new Integer(lengthPropertyValue);
return super.get(name, start);
}
/**
* Override ScriptableObject's has, get, and set in order to define
* the "length" property of the function. <p>
*
* In particular, this method will ignore all attempts to set the
* "length" property and forward all other requests to ScriptableObject.
*
* @see org.mozilla.javascript.FunctionObject#setLength
*/
public void put(String name, Scriptable start, Object value) {
if (!name.equals("length"))
super.put(name, start, value);
}
/**
* Set the value of the "length" property.
*
* <p>Changing the value of the "length" property of a FunctionObject only
* affects the value retrieved from get() and does not affect the way
* the method itself is called. <p>
*
* The "length" property will be defined by default as the number
* of parameters of the method used to construct the FunctionObject,
* unless the method is a "varargs" form, in which case the "length"
* property will be defined to 1.
*
* @param length the new length
*/
public void setLength(short length) {
lengthPropertyValue = length;
}
// TODO: Make not public
/**
* Finds methods of a given name in a given class.
*
* <p>Searches <code>clazz</code> for methods with name
* <code>name</code>. Maintains a cache so that multiple
* lookups on the same class are cheap.
*
* @param clazz the class to search
* @param name the name of the methods to find
* @return an array of the found methods, or null if no methods
* by that name were found.
* @see java.lang.Class#getMethods
*/
public static Method[] findMethods(Class clazz, String name) {
Vector v = new Vector(5);
Method[] methods = clazz.getMethods();
for (int i=0; i < methods.length; i++) {
if (methods[i].getDeclaringClass() == clazz &&
methods[i].getName().equals(name)){
v.addElement(methods[i]);
}
}
if (v.size() == 0) {
return null;
}
Method[] result = new Method[v.size()];
v.copyInto(result);
return result;
}
/**
* Define this function as a JavaScript constructor.
* <p>
* Sets up the "prototype" and "constructor" properties. Also
* calls setParent and setPrototype with appropriate values.
* Then adds the function object as a property of the given scope, using
* <code>prototype.getClassName()</code>
* as the name of the property.
*
* @param scope the scope in which to define the constructor (typically
* the global object)
* @param prototype the prototype object
* @see org.mozilla.javascript.Scriptable#setParentScope
* @see org.mozilla.javascript.Scriptable#setPrototype
* @see org.mozilla.javascript.Scriptable#getClassName
*/
public void addAsConstructor(Scriptable scope, Scriptable prototype) {
setParentScope(scope);
setPrototype(getFunctionPrototype(scope));
prototype.setParentScope(this);
final int attr = ScriptableObject.DONTENUM |
ScriptableObject.PERMANENT |
ScriptableObject.READONLY;
defineProperty("prototype", prototype, attr);
String name = prototype.getClassName();
if (!name.equals("With")) {
// A "With" object would delegate these calls to the prototype:
// not the right thing to do here!
if (prototype instanceof ScriptableObject) {
((ScriptableObject) prototype).defineProperty("constructor",
this, attr);
} else {
prototype.put("constructor", prototype, this);
}
}
if (scope instanceof ScriptableObject) {
((ScriptableObject) scope).defineProperty(name, this,
ScriptableObject.DONTENUM);
} else {
scope.put(name, scope, this);
}
setParentScope(scope);
}
static public Object convertArg(Scriptable scope,
Object arg, Class desired)
{
if (desired == ScriptRuntime.BooleanClass
|| desired == Boolean.TYPE)
return ScriptRuntime.toBoolean(arg) ? Boolean.TRUE
: Boolean.FALSE;
else if (desired == ScriptRuntime.StringClass)
return ScriptRuntime.toString(arg);
else if (desired == ScriptRuntime.IntegerClass
|| desired == Integer.TYPE)
return new Integer(ScriptRuntime.toInt32(arg));
else if (desired == ScriptRuntime.DoubleClass
|| desired == Double.TYPE)
return new Double(ScriptRuntime.toNumber(arg));
else if (desired == ScriptRuntime.ScriptableClass)
return ScriptRuntime.toObject(scope, arg);
else {
Object[] errArgs = { desired.getName() };
throw Context.reportRuntimeError(
Context.getMessage("msg.cant.convert", errArgs));
}
}
/**
* Performs conversions on argument types if needed and
* invokes the underlying Java method or constructor.
* <p>
* Implements Function.call.
*
* @see org.mozilla.javascript.Function#call
* @exception JavaScriptException if the underlying Java method or constructor
* threw an exception
*/
public Object call(Context cx, Scriptable scope, Scriptable thisObj,
Object[] args)
throws JavaScriptException
{
if (parmsLength < 0)
return callVarargs(cx, thisObj, args, false);
if (!isStatic) {
// OPT: cache "clazz"?
Class clazz = method != null ? method.getDeclaringClass()
: ctor.getDeclaringClass();
Scriptable p = thisObj;
while (p != null && !clazz.isInstance(p)) {
// Walk up the prototype chain to find an object to call the
// method on
p = p.getPrototype();
}
if (p == null) {
// Couldn't find an object to call this on.
Object[] errArgs = { names[0] };
throw Context.reportRuntimeError(
Context.getMessage("msg.incompat.call", errArgs));
}
thisObj = p;
}
Object[] invokeArgs;
int i;
if (parmsLength == args.length) {
invokeArgs = args;
// avoid copy loop if no conversions needed
i = (types == null) ? parmsLength : 0;
} else {
invokeArgs = new Object[parmsLength];
i = 0;
}
for (; i < parmsLength; i++) {
Object arg = (i < args.length)
? args[i]
: Undefined.instance;
if (types != null) {
arg = convertArg(this, arg, types[i]);
}
invokeArgs[i] = arg;
}
try {
Object result = (method != null)
? method.invoke(thisObj, invokeArgs)
: ctor.newInstance(invokeArgs);
return hasVoidReturn ? Undefined.instance : result;
}
catch (InvocationTargetException e) {
throw JavaScriptException.wrapException(scope, e);
}
catch (IllegalAccessException e) {
throw WrappedException.wrapException(e);
}
catch (InstantiationException e) {
throw WrappedException.wrapException(e);
}
}
/**
* Performs conversions on argument types if needed and
* invokes the underlying Java method or constructor
* to create a new Scriptable object.
* <p>
* Implements Function.construct.
*
* @param cx the current Context for this thread
* @param scope the scope to execute the function relative to. This
* set to the value returned by getParentScope() except
* when the function is called from a closure.
* @param args arguments to the constructor
* @see org.mozilla.javascript.Function#construct
* @exception JavaScriptException if the underlying Java method or constructor
* threw an exception
*/
public Scriptable construct(Context cx, Scriptable scope, Object[] args)
throws JavaScriptException
{
if (method == null || parmsLength == VARARGS_CTOR) {
Scriptable result;
if (method != null) {
// Ugly: allow variable-arg constructors that need access to the
// scope to get it from the Context. Cleanest solution would be
// to modify the varargs form, but that would require users with
// the old form to change their code.
cx.ctorScope = scope;
result = (Scriptable) callVarargs(cx, null, args, true);
cx.ctorScope = null;
} else {
result = (Scriptable) call(cx, scope, null, args);
}
if (result.getPrototype() == null)
result.setPrototype(getClassPrototype());
if (result.getParentScope() == null) {
Scriptable parent = getParentScope();
if (result != parent)
result.setParentScope(parent);
}
return result;
}
return super.construct(cx, scope, args);
}
private Object callVarargs(Context cx, Scriptable thisObj, Object[] args,
boolean inNewExpr)
throws JavaScriptException
{
try {
if (parmsLength == VARARGS_METHOD) {
Object[] invokeArgs = { cx, thisObj, args, this };
Object result = method.invoke(null, invokeArgs);
return hasVoidReturn ? Undefined.instance : result;
} else {
Boolean b = inNewExpr ? Boolean.TRUE : Boolean.FALSE;
Object[] invokeArgs = { cx, args, this, b };
return (method == null)
? ctor.newInstance(invokeArgs)
: method.invoke(null, invokeArgs);
}
}
catch (InvocationTargetException e) {
Throwable target = e.getTargetException();
if (target instanceof EvaluatorException)
throw (EvaluatorException) target;
Scriptable scope = thisObj == null ? this : thisObj;
throw JavaScriptException.wrapException(scope, target);
}
catch (IllegalAccessException e) {
throw WrappedException.wrapException(e);
}
catch (InstantiationException e) {
throw WrappedException.wrapException(e);
}
}
boolean isVarArgsMethod() {
return parmsLength == VARARGS_METHOD;
}
boolean isVarArgsConstructor() {
return parmsLength == VARARGS_CTOR;
}
private static final short VARARGS_METHOD = -1;
private static final short VARARGS_CTOR = -2;
Method method;
Constructor ctor;
private Class[] types;
private short parmsLength;
private short lengthPropertyValue;
private boolean hasVoidReturn;
private boolean isStatic;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,126 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
// API class
package org.mozilla.javascript;
import java.util.Vector;
/**
* Class ImporterTopLevel
*
* This class defines a ScriptableObject that can be instantiated
* as a top-level ("global") object to provide functionality similar
* to Java's "import" statement.
* <p>
* This class can be used to create a top-level scope using the following code:
* <pre>
* Scriptable scope = cx.initStandardObjects(new ImporterTopLevel());
* </pre>
* Then JavaScript code will have access to the following methods:
* <ul>
* <li>importClass - will "import" a class by making its unqualified name
* available as a property of the top-level scope
* <li>importPackage - will "import" all the classes of the package by
* searching for unqualified names as classes qualified
* by the given package.
* </ul>
* The following code from the shell illustrates this use:
* <pre>
* js> importClass(java.io.File)
* js> f = new File('help.txt')
* help.txt
* js> importPackage(java.util)
* js> v = new Vector()
* []
*
* @author Norris Boyd
*/
public class ImporterTopLevel extends ScriptableObject {
public ImporterTopLevel() {
String[] names = { "importClass", "importPackage" };
try {
this.defineFunctionProperties(names, ImporterTopLevel.class,
ScriptableObject.DONTENUM);
} catch (PropertyException e) {
throw new Error(); // should never happen
}
}
public String getClassName() {
return "global";
}
public Object get(String name, Scriptable start) {
Object result = super.get(name, start);
if (result == NOT_FOUND && importedPackages != null) {
for (int i=0; i < importedPackages.size(); i++) {
Object o = importedPackages.elementAt(i);
NativeJavaPackage p = (NativeJavaPackage) o;
Object v = p.getPkgProperty(name, start, false);
if (v != null && !(v instanceof NativeJavaPackage)) {
if (result == NOT_FOUND) {
result = v;
} else {
String[] args = { result.toString(), v.toString() };
throw Context.reportRuntimeError(
Context.getMessage("msg.ambig.import",
args));
}
}
}
}
return result;
}
public void importClass(Object cl) {
if (!(cl instanceof NativeJavaClass)) {
String[] args = { Context.toString(cl) };
throw Context.reportRuntimeError(
Context.getMessage("msg.not.class", args));
}
String s = ((NativeJavaClass) cl).getClassObject().getName();
String n = s.substring(s.lastIndexOf('.')+1);
if (this.has(n, this)) {
String[] args = { n };
throw Context.reportRuntimeError(
Context.getMessage("msg.prop.defined", args));
}
this.defineProperty(n, cl, DONTENUM);
}
public void importPackage(Object pkg) {
if (importedPackages == null)
importedPackages = new Vector();
if (!(pkg instanceof NativeJavaPackage)) {
String[] args = { Context.toString(pkg) };
throw Context.reportRuntimeError(
Context.getMessage("msg.not.pkg", args));
}
for (int i=0; i < importedPackages.size(); i++) {
if (pkg == importedPackages.elementAt(i))
return; // allready in list
}
importedPackages.addElement(pkg);
}
private Vector importedPackages;
}

View File

@@ -0,0 +1,55 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
package org.mozilla.javascript;
class InterpretedFunction extends NativeFunction {
InterpretedFunction(InterpreterData theData, Context cx)
{
itsData = theData;
// probably too much copying going on from theData to the InterpretedFunction object
// should pass them as parameters - unless we need them in the data block anyway?
names = new String[itsData.itsVariableTable.size() + 1];
names[0] = itsData.itsName;
for (int i = 0; i < itsData.itsVariableTable.size(); i++)
names[i + 1] = itsData.itsVariableTable.getName(i);
argCount = (short)itsData.itsVariableTable.getParameterCount();
source = itsData.itsSource;
nestedFunctions = itsData.itsNestedFunctions;
version = (short)cx.getLanguageVersion();
}
public Object call(Context cx, Scriptable scope, Scriptable thisObj,
Object[] args)
throws JavaScriptException
{
if (itsData.itsNeedsActivation)
scope = ScriptRuntime.initVarObj(cx, scope, this, thisObj, args);
itsData.itsCX = cx;
itsData.itsScope = scope;
itsData.itsThisObj = thisObj;
itsData.itsInArgs = args;
return Interpreter.interpret(itsData);
}
InterpreterData itsData;
}

View File

@@ -0,0 +1,55 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
package org.mozilla.javascript;
public class InterpretedScript extends NativeScript {
InterpretedScript(InterpreterData theData, Context cx)
{
itsData = theData;
names = new String[itsData.itsVariableTable.size() + 1];
names[0] = "";
for (int i = 0; i < itsData.itsVariableTable.size(); i++)
names[i + 1] = itsData.itsVariableTable.getName(i);
nestedFunctions = itsData.itsNestedFunctions;
version = (short)cx.getLanguageVersion();
}
public Object exec(Context cx, Scriptable scope)
throws JavaScriptException
{
return call(cx, scope, scope, null);
}
public Object call(Context cx, Scriptable scope,
Scriptable thisObj, Object[] args)
throws JavaScriptException
{
scope = ScriptRuntime.initScript(cx, scope, this, thisObj);
itsData.itsCX = cx;
itsData.itsScope = scope;
itsData.itsThisObj = thisObj;
itsData.itsInArgs = args;
return Interpreter.interpret(itsData);
}
InterpreterData itsData;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,80 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
package org.mozilla.javascript;
import java.util.Vector;
class InterpreterData {
static final int INITIAL_MAX_ICODE_LENGTH = 1024;
static final int INITIAL_STRINGTABLE_SIZE = 64;
static final int INITIAL_NUMBERTABLE_SIZE = 64;
InterpreterData(int lastICodeTop, int lastStringTableIndex,
int lastNumberTableIndex, Object securityDomain)
{
itsICodeTop = lastICodeTop == 0
? INITIAL_MAX_ICODE_LENGTH
: lastICodeTop * 2;
itsICode = new byte[itsICodeTop];
itsStringTable = new String[lastStringTableIndex == 0
? INITIAL_STRINGTABLE_SIZE
: lastStringTableIndex * 2];
itsNumberTable = new Number[lastNumberTableIndex == 0
? INITIAL_NUMBERTABLE_SIZE
: lastNumberTableIndex * 2];
if (securityDomain == null && Context.isSecurityDomainRequired())
throw new SecurityException("Required security context missing");
this.securityDomain = securityDomain;
}
VariableTable itsVariableTable;
String itsName;
String itsSource;
boolean itsNeedsActivation;
String[] itsStringTable;
int itsStringTableIndex;
Number[] itsNumberTable;
int itsNumberTableIndex;
InterpretedFunction[] itsNestedFunctions;
Object[] itsRegExpLiterals;
byte[] itsICode;
int itsICodeTop;
int itsMaxLocals;
int itsMaxArgs;
int itsMaxStack;
int itsMaxTryDepth;
Object securityDomain;
Context itsCX;
Scriptable itsScope;
Scriptable itsThisObj;
Object[] itsInArgs;
}

View File

@@ -0,0 +1,648 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
package org.mozilla.javascript;
import org.mozilla.classfile.*;
import java.lang.reflect.*;
import java.io.*;
import java.util.*;
public class JavaAdapter extends ScriptableObject {
public String getClassName() {
return "JavaAdapter";
}
public static Object js_JavaAdapter(Context cx, Object[] args,
Function ctorObj, boolean inNewExpr)
throws InstantiationException, NoSuchMethodException,
IllegalAccessException, InvocationTargetException,
ClassNotFoundException
{
Class superClass = Object.class;
Class[] intfs = new Class[args.length-1];
int interfaceCount = 0;
for (int i=0; i < args.length-1; i++) {
if (!(args[i] instanceof NativeJavaClass)) {
// TODO: report error
throw new RuntimeException("expected java class object");
}
Class c = ((NativeJavaClass) args[i]).getClassObject();
if (!c.isInterface()) {
superClass = c;
break;
}
intfs[interfaceCount++] = c;
}
StringBuffer sb = new StringBuffer("adapter");
sb.append(serial++);
Class[] interfaces = new Class[interfaceCount];
System.arraycopy(intfs, 0, interfaces, 0, interfaceCount);
Scriptable obj = (Scriptable) args[args.length - 1];
Class adapterClass = createAdapterClass(cx, obj, sb.toString(),
superClass, interfaces,
null, null);
Class[] ctorParms = { FlattenedObject.class };
Object[] ctorArgs = { new FlattenedObject(obj) };
Object v = adapterClass.getConstructor(ctorParms).newInstance(ctorArgs);
return cx.toObject(v, ScriptableObject.getTopLevelScope(ctorObj));
}
public static Class createAdapterClass(Context cx, Scriptable jsObj,
String name, Class superClass,
Class[] interfaces,
String scriptClassName,
ClassNameHelper nameHelper)
throws ClassNotFoundException
{
ClassFileWriter cfw = new ClassFileWriter(name,
superClass.getName(),
"<adapter>");
cfw.addField("o", "Lorg/mozilla/javascript/FlattenedObject;",
ClassFileWriter.ACC_PRIVATE);
cfw.addField("self", "Lorg/mozilla/javascript/Scriptable;",
(short) (ClassFileWriter.ACC_PUBLIC |
ClassFileWriter.ACC_FINAL));
int interfacesCount = interfaces == null ? 0 : interfaces.length;
for (int i=0; i < interfacesCount; i++) {
if (interfaces[i] != null)
cfw.addInterface(interfaces[i].getName());
}
generateCtor(cfw, name, superClass);
if (scriptClassName != null)
generateEmptyCtor(cfw, name, superClass, scriptClassName);
Hashtable generatedOverrides = new Hashtable();
// if abstract class was specified, then generate appropriate overrides.
for (int i = 0; i < interfacesCount; i++) {
Method[] methods = interfaces[i].getMethods();
for (int j = 0; j < methods.length; j++) {
Method method = methods[j];
int mods = method.getModifiers();
if (Modifier.isStatic(mods) || Modifier.isFinal(mods))
continue;
// make sure to generate only one instance of a particular
// method/signature.
String methodKey = getMethodSignature(method);
if (! generatedOverrides.containsKey(methodKey)) {
generateOverride(cfw, name, method);
generatedOverrides.put(methodKey, methodKey);
}
}
}
// Now, go through the superclasses methods, checking for abstract
// methods or additional methods to override.
FlattenedObject obj = jsObj != null
? new FlattenedObject(jsObj)
: null;
// generate any additional overrides that the object might contain.
Method[] methods = superClass.getMethods();
for (int j = 0; j < methods.length; j++) {
Method method = methods[j];
int mods = method.getModifiers();
if (Modifier.isStatic(mods) || Modifier.isFinal(mods))
continue;
// if a method is marked abstract, must implement it or the
// resulting class won't be instantiable. otherwise, if the object
// has a property of the same name, then an override is intended.
if (Modifier.isAbstract(mods) ||
(obj != null && obj.hasProperty(method.getName())))
{
// make sure to generate only one instance of a particular
// method/signature.
String methodKey = getMethodSignature(method);
if (! generatedOverrides.containsKey(methodKey)) {
generateOverride(cfw, name, method);
generatedOverrides.put(methodKey, method);
}
}
}
// TODO: generate Java methods, fields for remaining properties that
// are not overrides? Probably not necessary to generate methods
// that aren't overrides.
ByteArrayOutputStream out = new ByteArrayOutputStream(512);
try {
cfw.write(out);
}
catch (IOException ioe) {
throw new RuntimeException("unexpected IOException");
}
byte[] bytes = out.toByteArray();
if (nameHelper != null && nameHelper.getGeneratingDirectory() != null)
{
try {
int lastDot = name.lastIndexOf('.');
if (lastDot != -1)
name = name.substring(lastDot+1);
String filename = nameHelper.getTargetClassFileName(name);
FileOutputStream file = new FileOutputStream(filename);
file.write(bytes);
file.close();
}
catch (IOException iox) {
throw WrappedException.wrapException(iox);
}
return null;
}
SecuritySupport ss = cx.getSecuritySupport();
if (ss != null) {
Object securityDomain = cx.getSecurityDomainForStackDepth(-1);
return ss.defineClass(name, bytes, securityDomain);
} else {
if (classLoader == null)
classLoader = new MyClassLoader();
classLoader.defineClass(name, bytes);
return classLoader.loadClass(name, true);
}
}
/**
* Utility method, which dynamically binds a Context to the current thread,
* if none already exists.
*/
public static Object callMethod(FlattenedObject object, Object methodId,
Object[] args)
{
Context cx = Context.enter();
try {
if (object.hasProperty(methodId))
return object.callMethod(methodId, args);
} catch (PropertyException ex) {
// shouldn't occur
} catch (NotAFunctionException ex) {
// TODO: could occur
} catch (JavaScriptException ex) {
// TODO: could occur
/*
} catch (Exception ex) {
// TODO: wouldn't it be better to let the exception propagate
// up so that it could be dealt with by the calling code?
ex.printStackTrace(System.err);
throw new Error(ex.getMessage());
*/
} finally {
Context.exit();
}
return Context.getUndefinedValue();
}
private static void generateCtor(ClassFileWriter cfw, String name,
Class superClass)
{
cfw.startMethod("<init>",
"(Lorg/mozilla/javascript/FlattenedObject;)V",
ClassFileWriter.ACC_PUBLIC);
// Invoke base class constructor
cfw.add(ByteCode.ALOAD_0); // this
cfw.add(ByteCode.INVOKESPECIAL,
superClass.getName().replace('.', '/'),
"<init>", "()", "V");
/*
// Set the prototype of the js object to be a LiveConnect
// wapper of the generated class's object
cfw.add(ByteCode.ALOAD_1); // first arg
cfw.add(ByteCode.INVOKEVIRTUAL,
"org/mozilla/javascript/FlattenedObject",
"getObject", "()",
"Lorg/mozilla/javascript/Scriptable;");
cfw.add(ByteCode.ALOAD_0); // this
cfw.add(ByteCode.INVOKESTATIC,
"org/mozilla/javascript/ScriptRuntime",
"setAdapterProto",
"(Lorg/mozilla/javascript/Scriptable;" +
"Ljava/lang/Object;)",
"V");
*/
// Save parameter in instance variable
cfw.add(ByteCode.ALOAD_0); // this
cfw.add(ByteCode.ALOAD_1); // first arg
cfw.add(ByteCode.PUTFIELD, name, "o",
"Lorg/mozilla/javascript/FlattenedObject;");
// Store Scriptable object in "self", a public instance variable,
// so scripts can read it.
cfw.add(ByteCode.ALOAD_0); // this
cfw.add(ByteCode.ALOAD_1); // first arg
cfw.add(ByteCode.INVOKEVIRTUAL,
"org/mozilla/javascript/FlattenedObject",
"getObject", "()",
"Lorg/mozilla/javascript/Scriptable;");
cfw.add(ByteCode.PUTFIELD, name, "self",
"Lorg/mozilla/javascript/Scriptable;");
cfw.add(ByteCode.RETURN);
cfw.stopMethod((short)20, null); // TODO: magic number "20"
}
private static void generateEmptyCtor(ClassFileWriter cfw, String name,
Class superClass,
String scriptClassName)
{
cfw.startMethod("<init>", "()V", ClassFileWriter.ACC_PUBLIC);
// Invoke base class constructor
cfw.add(ByteCode.ALOAD_0); // this
cfw.add(ByteCode.INVOKESPECIAL,
superClass.getName().replace('.', '/'),
"<init>", "()", "V");
// Load script class
cfw.add(ByteCode.NEW, scriptClassName);
cfw.add(ByteCode.DUP);
cfw.add(ByteCode.INVOKESPECIAL, scriptClassName, "<init>", "()", "V");
// Run script and save resulting scope
cfw.add(ByteCode.INVOKESTATIC,
"org/mozilla/javascript/ScriptRuntime",
"runScript",
"(Lorg/mozilla/javascript/Script;)",
"Lorg/mozilla/javascript/FlattenedObject;");
cfw.add(ByteCode.ASTORE_1);
// Save the FlattenedObject in instance variable
cfw.add(ByteCode.ALOAD_0); // this
cfw.add(ByteCode.ALOAD_1); // the FlattenedObject
cfw.add(ByteCode.PUTFIELD, name, "o",
"Lorg/mozilla/javascript/FlattenedObject;");
// Store Scriptable object in "self", a public instance variable,
// so scripts can read it.
cfw.add(ByteCode.ALOAD_0); // this
cfw.add(ByteCode.ALOAD_1); // the FlattenedObject
cfw.add(ByteCode.INVOKEVIRTUAL,
"org/mozilla/javascript/FlattenedObject",
"getObject", "()",
"Lorg/mozilla/javascript/Scriptable;");
cfw.add(ByteCode.PUTFIELD, name, "self",
"Lorg/mozilla/javascript/Scriptable;");
// Set the prototype of the js object to be a LiveConnect
// wapper of the generated class's object
cfw.add(ByteCode.ALOAD_1); // the FlattenedObject
cfw.add(ByteCode.INVOKEVIRTUAL,
"org/mozilla/javascript/FlattenedObject",
"getObject", "()",
"Lorg/mozilla/javascript/Scriptable;");
cfw.add(ByteCode.ALOAD_0); // this
cfw.add(ByteCode.INVOKESTATIC,
"org/mozilla/javascript/ScriptRuntime",
"setAdapterProto",
"(Lorg/mozilla/javascript/Scriptable;" +
"Ljava/lang/Object;)",
"V");
cfw.add(ByteCode.RETURN);
cfw.stopMethod((short)20, null); // TODO: magic number "20"
}
/**
* Generates code to create a java.lang.Boolean, java.lang.Character or a
* java.lang.Double to wrap the specified primitive parameter. Leaves the
* wrapper object on the top of the stack.
*/
private static int generateWrapParam(ClassFileWriter cfw, int paramOffset,
Class paramType)
{
if (paramType.equals(Boolean.TYPE)) {
// wrap boolean values with java.lang.Boolean.
cfw.add(ByteCode.NEW, "java/lang/Boolean");
cfw.add(ByteCode.DUP);
cfw.add(ByteCode.ILOAD, paramOffset++);
cfw.add(ByteCode.INVOKESPECIAL, "java/lang/Boolean",
"<init>", "(Z)", "V");
} else
if (paramType.equals(Character.TYPE)) {
// Create a string of length 1 using the character parameter.
cfw.add(ByteCode.NEW, "java/lang/String");
cfw.add(ByteCode.DUP);
cfw.add(ByteCode.ICONST_1);
cfw.add(ByteCode.NEWARRAY, ByteCode.T_CHAR);
cfw.add(ByteCode.DUP);
cfw.add(ByteCode.ICONST_0);
cfw.add(ByteCode.ILOAD, paramOffset++);
cfw.add(ByteCode.CASTORE);
cfw.add(ByteCode.INVOKESPECIAL, "java/lang/String",
"<init>", "([C)", "V");
} else {
// convert all numeric values to java.lang.Double.
cfw.add(ByteCode.NEW, "java/lang/Double");
cfw.add(ByteCode.DUP);
String typeName = paramType.getName();
switch (typeName.charAt(0)) {
case 'b':
case 's':
case 'i':
// load an int value, convert to double.
cfw.add(ByteCode.ILOAD, paramOffset++);
cfw.add(ByteCode.I2D);
break;
case 'l':
// load a long, convert to double.
cfw.add(ByteCode.LLOAD, paramOffset);
cfw.add(ByteCode.L2D);
paramOffset += 2;
break;
case 'f':
// load a float, convert to double.
cfw.add(ByteCode.FLOAD, paramOffset++);
cfw.add(ByteCode.F2D);
break;
case 'd':
cfw.add(ByteCode.DLOAD, paramOffset);
paramOffset += 2;
break;
}
cfw.add(ByteCode.INVOKESPECIAL, "java/lang/Double",
"<init>", "(D)", "V");
}
return paramOffset;
}
/**
* Generates code to convert a wrapped value type to a primitive type.
* Handles unwrapping java.lang.Boolean, and java.lang.Number types.
* May need to map between char and java.lang.String as well.
* Generates the appropriate RETURN bytecode.
*/
private static void generateReturnResult(ClassFileWriter cfw,
Class retType)
{
// wrap boolean values with java.lang.Boolean, convert all other
// primitive values to java.lang.Double.
if (retType.equals(Boolean.TYPE)) {
cfw.add(ByteCode.INVOKESTATIC,
"org/mozilla/javascript/Context",
"toBoolean", "(Ljava/lang/Object;)",
"Z");
cfw.add(ByteCode.IRETURN);
} else if (retType.equals(Character.TYPE)) {
// characters are represented as strings in JavaScript.
// return the first character.
// first convert the value to a string if possible.
cfw.add(ByteCode.INVOKESTATIC,
"org/mozilla/javascript/Context",
"toString", "(Ljava/lang/Object;)",
"Ljava/lang/String;");
cfw.add(ByteCode.ICONST_0);
cfw.add(ByteCode.INVOKEVIRTUAL, "java/lang/String", "charAt",
"(I)", "C");
cfw.add(ByteCode.IRETURN);
} else if (retType.isPrimitive()) {
cfw.add(ByteCode.INVOKESTATIC,
"org/mozilla/javascript/Context",
"toNumber", "(Ljava/lang/Object;)",
"D");
String typeName = retType.getName();
switch (typeName.charAt(0)) {
case 'b':
case 's':
case 'i':
cfw.add(ByteCode.D2I);
cfw.add(ByteCode.IRETURN);
break;
case 'l':
cfw.add(ByteCode.D2L);
cfw.add(ByteCode.LRETURN);
break;
case 'f':
cfw.add(ByteCode.D2F);
cfw.add(ByteCode.FRETURN);
break;
case 'd':
cfw.add(ByteCode.DRETURN);
break;
default:
throw new RuntimeException("Unexpected return type " +
retType.toString());
}
} else if (retType.equals(String.class)) {
cfw.add(ByteCode.INVOKESTATIC,
"org/mozilla/javascript/Context",
"toString", "(Ljava/lang/Object;)",
"Ljava/lang/String;");
cfw.add(ByteCode.ARETURN);
} else if (retType.equals(Scriptable.class)) {
cfw.add(ByteCode.ALOAD_0); // load 'this' to find scope from
cfw.add(ByteCode.INVOKESTATIC,
"org/mozilla/javascript/Context",
"toObject",
"(Ljava/lang/Object;" +
"Lorg/mozilla/javascript/Scriptable;)",
"Lorg/mozilla/javascript/Scriptable;");
cfw.add(ByteCode.ARETURN);
} else {
// If it is a wrapped type, cast to Wrapper and call unwrap()
cfw.add(ByteCode.DUP);
cfw.add(ByteCode.INSTANCEOF, "org/mozilla/javascript/Wrapper");
// skip 3 for IFEQ, 3 for CHECKCAST, and 5 for INVOKEINTERFACE
cfw.add(ByteCode.IFEQ, 11);
cfw.add(ByteCode.CHECKCAST, "org/mozilla/javascript/Wrapper");
cfw.add(ByteCode.INVOKEINTERFACE,
"org/mozilla/javascript/Wrapper",
"unwrap", "()", "Ljava/lang/Object;");
// If Undefined, return null
cfw.add(ByteCode.DUP);
cfw.add(ByteCode.INSTANCEOF, "org/mozilla/javascript/Undefined");
// skip 3 for IFEQ, 1 for ACONST_NULL, 1 for ARETURN
cfw.add(ByteCode.IFEQ, 5);
cfw.add(ByteCode.ACONST_NULL);
cfw.add(ByteCode.ARETURN);
// Now cast to return type
String retTypeStr = retType.getName().replace('.', '/');
cfw.add(ByteCode.CHECKCAST, retTypeStr);
cfw.add(ByteCode.ARETURN);
}
}
private static void generateOverride(ClassFileWriter cfw, String genName,
Method m)
{
Class[] parms = m.getParameterTypes();
StringBuffer sb = new StringBuffer();
sb.append('(');
short arrayLocal = 1; // includes this.
for (int i = 0; i < parms.length; i++) {
Class type = parms[i];
appendTypeString(sb, type);
if (type.equals(Long.TYPE) || type.equals(Double.TYPE))
arrayLocal += 2;
else
arrayLocal += 1;
}
sb.append(')');
appendTypeString(sb, m.getReturnType());
String methodSignature = sb.toString();
// System.out.println("generating " + m.getName() + methodSignature);
// System.out.flush();
cfw.startMethod(m.getName(), methodSignature,
ClassFileWriter.ACC_PUBLIC);
cfw.add(ByteCode.BIPUSH, (byte) parms.length); // > 255 parms?
cfw.add(ByteCode.ANEWARRAY, "java/lang/Object");
cfw.add(ByteCode.ASTORE, arrayLocal);
// allocate a local variable to store the scope used to wrap native objects.
short scopeLocal = (short) (arrayLocal + 1);
boolean loadedScope = false;
int paramOffset = 1;
for (int i = 0; i < parms.length; i++) {
cfw.add(ByteCode.ALOAD, arrayLocal);
cfw.add(ByteCode.BIPUSH, i);
if (parms[i].isPrimitive()) {
paramOffset = generateWrapParam(cfw, paramOffset, parms[i]);
} else {
// An arbitary Java object; call Context.toObject to wrap in
// a Scriptable object
cfw.add(ByteCode.ALOAD, paramOffset++);
if (! loadedScope) {
// load this.self into a local the first time it's needed.
// it will provide the scope needed by Context.toObject().
cfw.add(ByteCode.ALOAD_0);
cfw.add(ByteCode.GETFIELD, genName, "self",
"Lorg/mozilla/javascript/Scriptable;");
cfw.add(ByteCode.ASTORE, scopeLocal);
loadedScope = true;
}
cfw.add(ByteCode.ALOAD, scopeLocal);
// Get argument Class
cfw.addLoadConstant(parms[i].getName());
cfw.add(ByteCode.INVOKESTATIC,
"java/lang/Class",
"forName",
"(Ljava/lang/String;)",
"Ljava/lang/Class;");
cfw.add(ByteCode.INVOKESTATIC,
"org/mozilla/javascript/Context",
"toObject",
"(Ljava/lang/Object;" +
"Lorg/mozilla/javascript/Scriptable;" +
"Ljava/lang/Class;)",
"Lorg/mozilla/javascript/Scriptable;");
}
cfw.add(ByteCode.AASTORE);
}
cfw.add(ByteCode.ALOAD_0); // this
cfw.add(ByteCode.GETFIELD, genName, "o",
"Lorg/mozilla/javascript/FlattenedObject;");
cfw.addLoadConstant(m.getName());
cfw.add(ByteCode.ALOAD, arrayLocal);
// go through utility method, which creates a Context to run the
// method in.
cfw.add(ByteCode.INVOKESTATIC,
"org/mozilla/javascript/JavaAdapter",
"callMethod",
"(Lorg/mozilla/javascript/FlattenedObject;" +
"Ljava/lang/Object;[Ljava/lang/Object;)",
"Ljava/lang/Object;");
Class retType = m.getReturnType();
if (retType.equals(Void.TYPE)) {
cfw.add(ByteCode.POP);
cfw.add(ByteCode.RETURN);
} else {
generateReturnResult(cfw, retType);
}
cfw.stopMethod((short)(scopeLocal + 1), null);
}
/**
* Returns a fully qualified method name concatenated with its signature.
*/
private static String getMethodSignature(Method method) {
Class[] parms = method.getParameterTypes();
StringBuffer sb = new StringBuffer();
sb.append(method.getName());
sb.append('(');
for (int i = 0; i < parms.length; i++) {
Class type = parms[i];
appendTypeString(sb, type);
}
sb.append(')');
appendTypeString(sb, method.getReturnType());
return sb.toString();
}
private static StringBuffer appendTypeString(StringBuffer sb, Class type)
{
while (type.isArray()) {
sb.append('[');
type = type.getComponentType();
}
if (type.isPrimitive()) {
if (type.equals(Boolean.TYPE)) {
sb.append('Z');
} else
if (type.equals(Long.TYPE)) {
sb.append('J');
} else {
String typeName = type.getName();
sb.append(Character.toUpperCase(typeName.charAt(0)));
}
} else {
sb.append('L');
sb.append(type.getName().replace('.', '/'));
sb.append(';');
}
return sb;
}
static final class MyClassLoader extends ClassLoader {
public Class defineClass(String name, byte data[]) {
return super.defineClass(name, data, 0, data.length);
}
protected Class loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
Class clazz = findLoadedClass(name);
if (clazz == null) {
ClassLoader loader = getClass().getClassLoader();
if (loader != null)
return loader.loadClass(name);
clazz = findSystemClass(name);
}
if (resolve)
resolveClass(clazz);
return clazz;
}
private java.util.Hashtable loaded;
}
private static int serial;
private static MyClassLoader classLoader;
}

View File

@@ -0,0 +1,412 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
package org.mozilla.javascript;
import java.lang.reflect.*;
import java.util.Hashtable;
import java.util.Enumeration;
/**
*
* @author Mike Shaver
* @author Norris Boyd
* @see NativeJavaObject
* @see NativeJavaClass
*/
class JavaMembers {
JavaMembers(Scriptable scope, Class cl) {
this.members = new Hashtable(23);
this.staticMembers = new Hashtable(7);
this.cl = cl;
reflect(scope, cl);
}
boolean has(String name, boolean isStatic) {
Hashtable ht = isStatic ? staticMembers : members;
Object obj = ht.get(name);
if (obj != null) {
return true;
}
else {
Member member = this.findExplicitFunction(name, isStatic);
return member != null;
}
}
Object get(Scriptable scope, String name, Object javaObject,
boolean isStatic)
{
Hashtable ht = isStatic ? staticMembers : members;
Object member = ht.get(name);
if (!isStatic && member == null) {
// Try to get static member from instance (LC3)
member = staticMembers.get(name);
}
if (member == null) {
member = this.getExplicitFunction(scope, name,
javaObject, isStatic);
if (member == null)
return Scriptable.NOT_FOUND;
}
if (member instanceof Scriptable)
return member;
Field field = (Field) member;
Object rval;
try {
rval = field.get(isStatic ? null : javaObject);
} catch (IllegalAccessException accEx) {
throw new RuntimeException("unexpected IllegalAccessException "+
"accessing Java field");
}
// Need to wrap the object before we return it.
Class fieldType = field.getType();
scope = ScriptableObject.getTopLevelScope(scope);
return NativeJavaObject.wrap(scope, rval, fieldType);
}
Member findExplicitFunction(String name, boolean isStatic) {
Hashtable ht = isStatic ? staticMembers : members;
int sigStart = name.indexOf('(');
Object member = null;
Member[] methodsOrCtors = null;
NativeJavaMethod method = null;
boolean isCtor = (isStatic && sigStart == 0);
if (isCtor) {
// Explicit request for an overloaded constructor
methodsOrCtors = ctors;
}
else if (sigStart > 0) {
// Explicit request for an overloaded method
String trueName = name.substring(0,sigStart);
Object obj = ht.get(trueName);
if (!isStatic && obj == null) {
// Try to get static member from instance (LC3)
obj = staticMembers.get(trueName);
}
if (obj != null && obj instanceof NativeJavaMethod) {
method = (NativeJavaMethod)obj;
methodsOrCtors = method.getMethods();
}
}
if (methodsOrCtors != null) {
for (int i = 0; i < methodsOrCtors.length; i++) {
String nameWithSig =
NativeJavaMethod.signature(methodsOrCtors[i]);
if (name.equals(nameWithSig)) {
return methodsOrCtors[i];
}
}
}
return null;
}
Object getExplicitFunction(Scriptable scope,
String name,
Object javaObject,
boolean isStatic) {
Hashtable ht = isStatic ? staticMembers : members;
Object member = null;
Member methodOrCtor = this.findExplicitFunction(name, isStatic);
if (methodOrCtor != null) {
Scriptable prototype =
ScriptableObject.getFunctionPrototype(scope);
if (methodOrCtor instanceof Constructor) {
NativeJavaConstructor fun =
new NativeJavaConstructor((Constructor)methodOrCtor);
fun.setParentScope(scope);
fun.setPrototype(prototype);
member = fun;
ht.put(name, fun);
}
else {
String trueName = methodOrCtor.getName();
member = ht.get(trueName);
if (member instanceof NativeJavaMethod &&
((NativeJavaMethod)member).getMethods().length > 1 ) {
NativeJavaMethod fun =
new NativeJavaMethod((Method)methodOrCtor, name);
fun.setParentScope(scope);
fun.setPrototype(prototype);
ht.put(name, fun);
member = fun;
}
}
}
return member;
}
public void put(String name, Object javaObject, Object value,
boolean isStatic)
{
Hashtable ht = isStatic ? staticMembers : members;
Object member = ht.get(name);
if (!isStatic && member == null) {
// Try to get static member from instance (LC3)
member = staticMembers.get(name);
}
if (member == null)
throw reportMemberNotFound(name);
if (member instanceof FieldAndMethods) {
member = ((FieldAndMethods) ht.get(name)).getField();
}
Field field = null;
try {
field = (Field) member;
field.set(javaObject, NativeJavaObject.coerceType(field.getType(),
value));
} catch (ClassCastException e) {
Object errArgs[] = { name };
throw Context.reportRuntimeError(Context.getMessage
("msg.java.method.assign",
errArgs));
} catch (IllegalAccessException accessEx) {
throw new RuntimeException("unexpected IllegalAccessException "+
"accessing Java field");
} catch (IllegalArgumentException argEx) {
Object errArgs[] = { value.getClass().getName(), field,
javaObject.getClass().getName() };
throw Context.reportRuntimeError(Context.getMessage(
"msg.java.internal.field.type", errArgs));
}
}
Object[] getIds(boolean isStatic) {
Hashtable ht = isStatic ? staticMembers : members;
int len = ht.size();
Object[] result = new Object[len];
Enumeration keys = ht.keys();
for (int i=0; i < len; i++)
result[i] = keys.nextElement();
return result;
}
Class getReflectedClass() {
return cl;
}
void reflectField(Field field) {
int mods = field.getModifiers();
if (!Modifier.isPublic(mods))
return;
boolean isStatic = Modifier.isStatic(mods);
Hashtable ht = isStatic ? staticMembers : members;
String name = field.getName();
Object member = ht.get(name);
if (member != null) {
if (member instanceof NativeJavaMethod) {
NativeJavaMethod method = (NativeJavaMethod) member;
Hashtable fmht = isStatic ? staticFieldAndMethods
: fieldAndMethods;
if (fmht == null) {
fmht = new Hashtable(11);
if (isStatic)
staticFieldAndMethods = fmht;
else
fieldAndMethods = fmht;
}
FieldAndMethods fam = new FieldAndMethods(method.getMethods(),
field);
fmht.put(name, fam);
ht.put(name, fam);
return;
}
if (member instanceof Field) {
Field oldField = (Field) member;
// beard:
// If an exception is thrown here, then JDirect classes on MRJ can't be used. JDirect
// classes implement multiple interfaces that each have a static "libraryInstance" field.
if (false) {
throw new RuntimeException("cannot have multiple Java " +
"fields with same name");
}
// If this newly reflected field shadows an inherited field, then replace it. Otherwise,
// since access to the field would be ambiguous from Java, no field should be reflected.
// For now, the first field found wins, unless another field explicitly shadows it.
if (oldField.getDeclaringClass().isAssignableFrom(field.getDeclaringClass()))
ht.put(name, field);
return;
}
throw new RuntimeException("unknown member type");
}
ht.put(name, field);
}
void reflectMethod(Scriptable scope, Method method) {
int mods = method.getModifiers();
if (!Modifier.isPublic(mods))
return;
boolean isStatic = Modifier.isStatic(mods);
Hashtable ht = isStatic ? staticMembers : members;
String name = method.getName();
NativeJavaMethod fun = (NativeJavaMethod) ht.get(name);
if (fun == null) {
fun = new NativeJavaMethod();
fun.setParentScope(scope);
fun.setPrototype(ScriptableObject.getFunctionPrototype(scope));
ht.put(name, fun);
fun.add(method);
}
else
fun.add(method);
}
void reflect(Scriptable scope, Class cl) {
// We reflect methods first, because we want overloaded field/method
// names to be allocated to the NativeJavaMethod before the field
// gets in the way.
Method[] methods = cl.getMethods();
for (int i = 0; i < methods.length; i++)
reflectMethod(scope, methods[i]);
Field[] fields = cl.getFields();
for (int i = 0; i < fields.length; i++)
reflectField(fields[i]);
ctors = cl.getConstructors();
}
Hashtable getFieldAndMethodsObjects(Object javaObject, boolean isStatic) {
Hashtable ht = isStatic ? staticFieldAndMethods : fieldAndMethods;
if (ht == null)
return null;
int len = ht.size();
Hashtable result = new Hashtable(len);
Enumeration e = ht.elements();
while (len-- > 0) {
FieldAndMethods fam = (FieldAndMethods) e.nextElement();
fam = (FieldAndMethods) fam.clone();
fam.setJavaObject(javaObject);
result.put(fam.getName(), fam);
}
return result;
}
Constructor[] getConstructors() {
return ctors;
}
static JavaMembers lookupClass(Scriptable scope, Class dynamicType,
Class staticType)
{
Class cl = dynamicType;
JavaMembers members = (JavaMembers) classTable.get(cl);
if (members != null)
return members;
if (staticType != null && staticType != dynamicType &&
!Modifier.isPublic(dynamicType.getModifiers()) &&
Modifier.isPublic(staticType.getModifiers()))
{
cl = staticType;
}
synchronized (classTable) {
members = (JavaMembers) classTable.get(cl);
if (members != null)
return members;
try {
members = new JavaMembers(scope, cl);
} catch (SecurityException e) {
// Reflection may fail for objects that are in a restricted
// access package (e.g. sun.*). If we get a security
// exception, try again with the static type. Otherwise,
// rethrow the exception.
if (cl != staticType)
members = new JavaMembers(scope, staticType);
else
throw e;
}
classTable.put(cl, members);
return members;
}
}
RuntimeException reportMemberNotFound(String memberName) {
Object errArgs[] = { cl.getName(),
memberName };
return Context.reportRuntimeError(
Context.getMessage("msg.java.member.not.found",
errArgs));
}
private static Hashtable classTable = new Hashtable();
private Class cl;
private Hashtable members;
private Hashtable fieldAndMethods;
private Hashtable staticMembers;
private Hashtable staticFieldAndMethods;
private Constructor[] ctors;
}
class FieldAndMethods extends NativeJavaMethod {
FieldAndMethods(Method[] methods, Field field) {
super(methods);
this.field = field;
}
void setJavaObject(Object javaObject) {
this.javaObject = javaObject;
}
String getName() {
return field.getName();
}
Field getField() {
return field;
}
public Object getDefaultValue(Class hint) {
if (hint == ScriptRuntime.FunctionClass)
return this;
Object rval;
try {
rval = field.get(javaObject);
} catch (IllegalAccessException accEx) {
throw Context.reportRuntimeError(Context.getMessage
("msg.java.internal.private", null));
}
rval = NativeJavaObject.wrap(this, rval, field.getType());
if (rval instanceof Scriptable) {
((Scriptable)rval).setParentScope(this);
((Scriptable)rval).setPrototype(parent.getPrototype());
}
return rval;
}
public Object clone() {
FieldAndMethods result = new FieldAndMethods(methods, field);
result.javaObject = javaObject;
return result;
}
private Field field;
private Object javaObject;
}

View File

@@ -0,0 +1,92 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
// API class
package org.mozilla.javascript;
import java.lang.reflect.InvocationTargetException;
/**
* Java reflection of JavaScript exceptions. (Possibly wrapping a Java exception.)
*
* @author Mike McCabe
*/
public class JavaScriptException extends Exception {
/**
* Create a JavaScript exception wrapping the given JavaScript value.
*
* Instances of this class are thrown by the JavaScript 'throw' keyword.
*
* @param value the JavaScript value thrown.
*/
public JavaScriptException(Object value) {
super(ScriptRuntime.toString(value));
this.value = value;
}
/**
* Get the exception message.
*
* <p>Will just convert the wrapped exception to a string.
*/
public String getMessage() {
return ScriptRuntime.toString(value);
}
static JavaScriptException wrapException(Scriptable scope,
Throwable exn)
{
if (exn instanceof InvocationTargetException)
exn = ((InvocationTargetException)exn).getTargetException();
if (exn instanceof JavaScriptException)
return (JavaScriptException)exn;
Object wrapper = NativeJavaObject.wrap(scope, exn, Throwable.class);
return new JavaScriptException(wrapper);
}
/**
* Get the exception value originally thrown. This may be a
* JavaScript value (null, undefined, Boolean, Number, String,
* Scriptable or Function) or a Java exception value thrown from a
* host object or from Java called through LiveConnect.
*
* @return the value wrapped by this exception
*/
public Object getValue() {
if (value != null && value instanceof Wrapper)
// this will also catch NativeStrings...
return ((Wrapper)value).unwrap();
else
return value;
}
/**
* The JavaScript exception value. This value is not
* intended for general use; if the JavaScriptException wraps a
* Java exception, getScriptableValue may return a Scriptable
* wrapping the original Java exception object.
*
* We would prefer to go through a getter to encapsulate the value,
* however that causes the bizarre error "nanosecond timeout value
* out of range" on the MS JVM.
* @serial
*/
Object value;
}

View File

@@ -0,0 +1,87 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
package org.mozilla.javascript;
public class Label {
private static final int FIXUPTABLE_SIZE = 8;
private static final boolean DEBUG = true;
public Label()
{
itsPC = -1;
}
public short getPC()
{
return itsPC;
}
public void fixGotos(byte theCodeBuffer[])
{
if (DEBUG) {
if ((itsPC == -1) && (itsFixupTable != null))
throw new RuntimeException("Unlocated label");
}
if (itsFixupTable != null) {
for (int i = 0; i < itsFixupTableTop; i++) {
int fixupSite = itsFixupTable[i];
// -1 to get delta from instruction start
short offset = (short)(itsPC - (fixupSite - 1));
theCodeBuffer[fixupSite++] = (byte)(offset >> 8);
theCodeBuffer[fixupSite] = (byte)offset;
}
}
itsFixupTable = null;
}
public void setPC(short thePC)
{
if (DEBUG) {
if ((itsPC != -1) && (itsPC != thePC))
throw new RuntimeException("Duplicate label");
}
itsPC = thePC;
}
public void addFixup(int fixupSite)
{
if (itsFixupTable == null) {
itsFixupTableTop = 1;
itsFixupTable = new int[FIXUPTABLE_SIZE];
itsFixupTable[0] = fixupSite;
}
else {
if (itsFixupTableTop == itsFixupTable.length) {
int oldLength = itsFixupTable.length;
int newTable[] = new int[oldLength + FIXUPTABLE_SIZE];
System.arraycopy(itsFixupTable, 0, newTable, 0, oldLength);
itsFixupTable = newTable;
}
itsFixupTable[itsFixupTableTop++] = fixupSite;
}
}
private short itsPC;
private int itsFixupTable[];
private int itsFixupTableTop;
}

View File

@@ -0,0 +1,63 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
package org.mozilla.javascript;
public class LabelTable {
private static final boolean DEBUGLABELS = false;
private static final int LabelTableSize = 32;
protected Label itsLabelTable[];
protected int itsLabelTableTop;
public int acquireLabel()
{
if (itsLabelTable == null) {
itsLabelTable = new Label[LabelTableSize];
itsLabelTable[0] = new Label();
itsLabelTableTop = 1;
return 0x80000000;
}
else {
if (itsLabelTableTop == itsLabelTable.length) {
Label oldTable[] = itsLabelTable;
itsLabelTable = new Label[itsLabelTableTop * 2];
System.arraycopy(oldTable, 0, itsLabelTable, 0, itsLabelTableTop);
}
itsLabelTable[itsLabelTableTop] = new Label();
int result = itsLabelTableTop++;
return result | 0x80000000;
}
}
public int markLabel(int theLabel, int pc)
{
if (DEBUGLABELS) {
if ((theLabel & 0x80000000) != 0x80000000)
throw new RuntimeException("Bad label, no biscuit");
}
theLabel &= 0x7FFFFFFF;
if (DEBUGLABELS) {
System.out.println("Marking label " + theLabel + " at " + pc);
}
itsLabelTable[theLabel].setPC((short)pc);
return theLabel | 0x80000000;
}
}

View File

@@ -0,0 +1,350 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
package org.mozilla.javascript;
import java.io.Reader;
import java.io.IOException;
/**
* An input buffer that combines fast character-based access with
* (slower) support for retrieving the text of the current line. It
* also supports building strings directly out of the internal buffer
* to support fast scanning with minimal object creation.
*
* Note that it is customized in several ways to support the
* TokenStream class, and should not be considered general.
*
* Credits to Kipp Hickman and John Bandhauer.
*
* @author Mike McCabe
*/
final class LineBuffer {
/*
* for smooth operation of getLine(), this should be greater than
* the length of any expected line. Currently, 256 is 3% slower
* than 4096 for large compiles, but seems safer given evaluateString.
* Strings for the scanner are are built with StringBuffers
* instead of directly out of the buffer whenever a string crosses
* a buffer boundary, so small buffer sizes will mean that more
* objects are created.
*/
static final int BUFLEN = 256;
LineBuffer(Reader in, int lineno) {
this.in = in;
this.lineno = lineno;
}
int read() throws IOException {
if (end == offset && !fill())
return -1;
// Do only a bitmask + branch per character, at the cost of
// three branches per low-bits-only character.
if ((buffer[offset] & '\ufff0') == 0) {
if (buffer[offset] == '\r') {
// if the next character is a newline, skip past it.
if ((offset + 1) < end) {
if (buffer[offset + 1] == '\n')
offset++;
} else {
// set a flag for fill(), in case the first char of the
// next fill is a newline.
lastWasCR = true;
}
}
else if (buffer[offset] != '\n') {
return (int) buffer[offset++];
}
offset++;
prevStart = lineStart;
lineStart = offset;
lineno++;
return '\n';
}
return (int) buffer[offset++];
}
void unread() {
if (offset == 0)
// We can get here when we're asked to unread() an
// implicit EOF_CHAR.
// This would also be wrong behavior in the general case,
// because a peek() could map a buffer.length offset to 0
// in the process of a fill(), and leave it there. But
// the scanner never calls peek() or a failed match()
// followed by unread()... this would violate 1-character
// lookahead. So we're OK.
return;
offset--;
if ((buffer[offset] & '\ufff0') == 0
&& (buffer[offset] == '\r' || buffer[offset] == '\n')) {
// back off from the line start we presumably just registered...
lineStart = prevStart;
lineno--;
}
}
int peek() throws IOException {
if (end == offset && !fill())
return -1;
if (buffer[offset] == '\r')
return '\n';
return buffer[offset];
}
boolean match(char c) throws IOException {
if (end == offset && !fill())
return false;
// This'd be a place where we'd need to map '\r' to '\n' and
// do other updates, but TokenStream never looks ahead for
// '\n', so we don't bother.
if (buffer[offset] == c) {
offset++;
return true;
}
return false;
}
// Reconstruct a source line from the buffers. This can be slow...
String getLine() {
StringBuffer result = new StringBuffer();
int start = lineStart;
if (start >= offset) {
// the line begins somewhere in the other buffer; get that first.
if (otherStart < otherEnd)
// if a line ending was seen in the other buffer... otherwise
// just ignore this strange case.
result.append(otherBuffer, otherStart,
otherEnd - otherStart);
start = 0;
}
// get the part of the line in the current buffer.
result.append(buffer, start, offset - start);
// Get the remainder of the line.
int i = offset;
while(true) {
if (i == buffer.length) {
// we're out of buffer, let's just expand it. We do
// this instead of reading into a StringBuffer to
// preserve the stream for later reads.
char[] newBuffer = new char[buffer.length * 2];
System.arraycopy(buffer, 0, newBuffer, 0, buffer.length);
buffer = newBuffer;
int charsRead = 0;
try {
charsRead = in.read(buffer, end, buffer.length - end);
} catch (IOException ioe) {
// ignore it, we're already displaying an error...
}
if (charsRead < 0)
break;
end += charsRead;
}
if (buffer[i] == '\r' || buffer[i] == '\n')
break;
i++;
}
result.append(buffer, offset, i - offset);
return result.toString();
}
// Get the offset of the current character, relative to
// the line that getLine() returns.
int getOffset() {
if (lineStart >= offset)
// The line begins somewhere in the other buffer.
return offset + (otherEnd - otherStart);
else
return offset - lineStart;
}
// Set a mark to indicate that the reader should begin
// accumulating characters for getString(). The string begins
// with the last character read.
void startString() {
if (offset == 0) {
// We can get here if startString is called after a peek()
// or failed match() with offset past the end of the
// buffer.
// We're at the beginning of the buffer, and the previous character
// (which we want to include) is at the end of the last one, so
// we just go to StringBuffer mode.
stringSoFar = new StringBuffer();
stringSoFar.append(otherBuffer, otherEnd - 1, 1);
stringStart = -1; // Set sentinel value.
} else {
// Support restarting strings
stringSoFar = null;
stringStart = offset - 1;
}
}
// Get a string consisting of the characters seen since the last
// startString.
String getString() {
String result;
/*
* There's one strange case here: If the character offset currently
* points to (which we never want to include in the string) is
* a newline, then if the previous character is a carriage return,
* we probably want to exclude that as well. If the offset is 0,
* then we hope that fill() handled excluding it from stringSoFar.
*/
int loseCR = (offset > 0 &&
buffer[offset] == '\n' && buffer[offset - 1] == '\r') ?
1 : 0;
if (stringStart != -1) {
// String mark is valid, and in this buffer.
result = new String(buffer, stringStart,
offset - stringStart - loseCR);
} else {
if (stringSoFar == null)
stringSoFar = new StringBuffer();
// Exclude cr as well as nl of newline. If offset is 0, then
// hopefully fill() did the right thing.
result = (stringSoFar.append(buffer, 0, offset - loseCR)).toString();
}
stringStart = -1;
stringSoFar = null;
return result;
}
boolean fill() throws IOException {
// not sure I care...
if (end - offset != 0)
throw new IOException("fill of non-empty buffer");
// If there's a string currently being accumulated, save
// off the progress.
/*
* Exclude an end-of-buffer carriage return. NOTE this is not
* fully correct in the general case, because we really only
* want to exclude the carriage return if it's followed by a
* linefeed at the beginning of the next buffer. But we fudge
* because the scanner doesn't do this.
*/
int loseCR = (offset > 0 && lastWasCR) ? 1 : 0;
if (stringStart != -1) {
// The mark is in the current buffer, save off from the mark to the
// end.
stringSoFar = new StringBuffer();
stringSoFar.append(buffer, stringStart, end - stringStart - loseCR);
stringStart = -1;
} else if (stringSoFar != null) {
// the string began prior to the current buffer, so save the
// whole current buffer.
stringSoFar.append(buffer, 0, end - loseCR);
}
// swap buffers
char[] tempBuffer = buffer;
buffer = otherBuffer;
otherBuffer = tempBuffer;
// allocate the buffers lazily, in case we're handed a short string.
if (buffer == null) {
buffer = new char[BUFLEN];
}
// buffers have switched, so move the newline marker.
otherStart = lineStart;
otherEnd = end;
// set lineStart to a sentinel value, unless this is the first
// time around.
prevStart = lineStart = (otherBuffer == null) ? 0 : buffer.length + 1;
offset = 0;
end = in.read(buffer, 0, buffer.length);
if (end < 0) {
end = 0;
// can't null buffers here, because a string might be retrieved
// out of the other buffer, and a 0-length string might be
// retrieved out of this one.
hitEOF = true;
return false;
}
// If the last character of the previous fill was a carriage return,
// then ignore a newline.
// There's another bizzare special case here. If lastWasCR is
// true, and we see a newline, and the buffer length is
// 1... then we probably just read the last character of the
// file, and returning after advancing offset is not the right
// thing to do. Instead, we try to ignore the newline (and
// likely get to EOF for real) by doing yet another fill().
if (lastWasCR) {
if (buffer[0] == '\n') {
offset++;
if (end == 1)
return fill();
}
lineStart = offset;
lastWasCR = false;
}
return true;
}
int getLineno() { return lineno; }
boolean eof() { return hitEOF; }
private Reader in;
private char[] otherBuffer = null;
private char[] buffer = null;
// Yes, there are too too many of these.
private int offset = 0;
private int end = 0;
private int otherEnd;
private int lineno;
private int lineStart = 0;
private int otherStart = 0;
private int prevStart = 0;
private boolean lastWasCR = false;
private boolean hitEOF = false;
private int stringStart = -1;
private StringBuffer stringSoFar = null;
}

View File

@@ -0,0 +1,96 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.0 (the "MozPL"); you may not use this file except in
* compliance with the MozPL. You may obtain a copy of the MozPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the MozPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the MozPL
* for the specific language governing rights and limitations under the
* MozPL.
*
* The Initial Developer of this code under the MozPL is Ian D. Stewart.
* Portions created by Ian D. Stewart are Copyright (C) 1998, 1999
* Ian D. Stewart.
* All Rights Reserved.
*/
/* This class provides a series of methods for accessing event listeners. */
package org.mozilla.javascript;
import java.util.Enumeration;
import java.util.Vector;
/**
* This class acts as central storage location for miscelanious
* event listeners. It provides methods for adding, removing
* and accessing listeners, both individually and collectively,
* by the listener interface implemented
*
* Note: This class performs the same functions as
* javax.swing.event.EventListenerList, and is provided
* primarily for implementations lacking the Swing packages
*
* @author Ian D. Stewart
* @since JavaScript-Java 1.4 rel 3
*/
public class ListenerCollection extends Vector {
/**
* Create a new ListenerCollection
*/
public ListenerCollection() {
super();
} // Constructor
/**
* Add a new listener to the collection
* @param listener the listener
*/
public void addListener(Object listener) {
this.addElement(listener);
}
/**
* Remove a listener from the collection
* @param listener the listener
*/
public void removeListener(Object listener) {
this.removeElement(listener);
}
/**
* Returns an Enumeration of all the listeners
* being stored in this collection
* @return an Enumeration of all listeners
*/
public Enumeration getAllListeners() {
return this.elements();
}
/**
* Return all the listeners in this collection which
* implement the specified interface
*
* @param iface the interface
* @return an array of listeners which implement the given
* interface
*/
public Object[] getListeners(Class iface) {
Vector array = new Vector();
for(Enumeration enum = getAllListeners();enum.hasMoreElements();) {
Object listener = enum.nextElement();
if(iface.isInstance(listener)) {
array.addElement(listener);
}
}
Object[] result = new Object[array.size()];
array.copyInto(result);
return result;
}
} // ListenerCollection
// end of ListenerCollection.java ...

View File

@@ -0,0 +1,62 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
package org.mozilla.javascript;
public class LocalVariable {
public LocalVariable(String name, boolean isParameter) {
itsName = name;
itsIsParameter = isParameter;
}
public void setIndex(int index){ itsIndex = index; }
public int getIndex() { return itsIndex; }
public void setIsParameter() { itsIsParameter = true; }
public boolean isParameter() { return itsIsParameter; }
public String getName() { return itsName; }
/**
* Return the starting PC where this variable is live, or -1
* if it is not a Java register.
*/
public int getStartPC() {
return -1;
}
/**
* Return the Java register number or -1 if it is not a Java register.
*/
public short getJRegister() {
return -1;
}
/**
* Return true if the local variable is a Java register with double type.
*/
public boolean isNumber() {
return false;
}
private String itsName;
private int itsIndex = -1;
private boolean itsIsParameter;
}

View File

@@ -0,0 +1,214 @@
#! gmake
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1999 Netscape Communications Corporation. All Rights
# Reserved.
#
# Makefile the core javascript classes.
#
# This Makefile is intended to be called from the toplevel Makefile.
#
# List files explicitly to exclude .java files in this dir we don't want
# to compile. Also hack in classfile stuff...
SOURCES = \
$(PATH_PREFIX)/Arguments.java \
$(PATH_PREFIX)/BinaryDigitReader.java \
$(PATH_PREFIX)/ClassDefinitionException.java \
$(PATH_PREFIX)/ClassNameHelper.java \
$(PATH_PREFIX)/Context.java \
$(PATH_PREFIX)/DeepBytecodeHook.java \
$(PATH_PREFIX)/DeepCallHook.java \
$(PATH_PREFIX)/DeepErrorReporterHook.java \
$(PATH_PREFIX)/DeepExecuteHook.java \
$(PATH_PREFIX)/DeepNewObjectHook.java \
$(PATH_PREFIX)/DeepScriptHook.java \
$(PATH_PREFIX)/DefaultErrorReporter.java \
$(PATH_PREFIX)/ErrorReporter.java \
$(PATH_PREFIX)/EvaluatorException.java \
$(PATH_PREFIX)/FlattenedObject.java \
$(PATH_PREFIX)/Function.java \
$(PATH_PREFIX)/FunctionNode.java \
$(PATH_PREFIX)/FunctionObject.java \
$(PATH_PREFIX)/IRFactory.java \
$(PATH_PREFIX)/ImporterTopLevel.java \
$(PATH_PREFIX)/InterpretedFunction.java \
$(PATH_PREFIX)/InterpretedScript.java \
$(PATH_PREFIX)/Interpreter.java \
$(PATH_PREFIX)/InterpreterData.java \
$(PATH_PREFIX)/JavaAdapter.java \
$(PATH_PREFIX)/JavaMembers.java \
$(PATH_PREFIX)/JavaScriptException.java \
$(PATH_PREFIX)/Label.java \
$(PATH_PREFIX)/LabelTable.java \
$(PATH_PREFIX)/LineBuffer.java \
$(PATH_PREFIX)/ListenerCollection.java \
$(PATH_PREFIX)/LocalVariable.java \
$(PATH_PREFIX)/NativeArray.java \
$(PATH_PREFIX)/NativeBoolean.java \
$(PATH_PREFIX)/NativeCall.java \
$(PATH_PREFIX)/NativeClosure.java \
$(PATH_PREFIX)/NativeDate.java \
$(PATH_PREFIX)/NativeFunction.java \
$(PATH_PREFIX)/NativeGlobal.java \
$(PATH_PREFIX)/NativeJavaArray.java \
$(PATH_PREFIX)/NativeJavaClass.java \
$(PATH_PREFIX)/NativeJavaConstructor.java \
$(PATH_PREFIX)/NativeJavaMethod.java \
$(PATH_PREFIX)/NativeJavaObject.java \
$(PATH_PREFIX)/NativeJavaPackage.java \
$(PATH_PREFIX)/NativeMath.java \
$(PATH_PREFIX)/NativeNumber.java \
$(PATH_PREFIX)/NativeObject.java \
$(PATH_PREFIX)/NativeScript.java \
$(PATH_PREFIX)/NativeString.java \
$(PATH_PREFIX)/NativeWith.java \
$(PATH_PREFIX)/Node.java \
$(PATH_PREFIX)/NodeTransformer.java \
$(PATH_PREFIX)/NotAFunctionException.java \
$(PATH_PREFIX)/Parser.java \
$(PATH_PREFIX)/PreorderNodeIterator.java \
$(PATH_PREFIX)/PropertyException.java \
$(PATH_PREFIX)/RegExpProxy.java \
$(PATH_PREFIX)/Script.java \
$(PATH_PREFIX)/ScriptRuntime.java \
$(PATH_PREFIX)/Scriptable.java \
$(PATH_PREFIX)/ScriptableObject.java \
$(PATH_PREFIX)/SecuritySupport.java \
$(PATH_PREFIX)/ShallowNodeIterator.java \
$(PATH_PREFIX)/SourceTextItem.java \
$(PATH_PREFIX)/SourceTextManager.java \
$(PATH_PREFIX)/TokenStream.java \
$(PATH_PREFIX)/Undefined.java \
$(PATH_PREFIX)/VariableTable.java \
$(PATH_PREFIX)/WrappedException.java \
$(PATH_PREFIX)/Wrapper.java \
$(PATH_PREFIX)/regexp/NativeRegExp.java \
$(PATH_PREFIX)/regexp/NativeRegExpCtor.java \
$(PATH_PREFIX)/regexp/RegExpImpl.java \
$(PATH_PREFIX)/regexp/SubString.java \
$(PATH_PREFIX)/../classfile/ByteCode.java \
$(PATH_PREFIX)/../classfile/ClassFileWriter.java\
$(NULL)
RESOURCEDIR = $(PATH_PREFIX)/resources
RESOURCES = $(RESOURCEDIR)/*.properties
# This must be evaluated in some context where the classes can be
# found; we can't use a simple translation from sources, because a
# .java file may produce more than one .class file.
# (use org/mozilla/classfile explicitly for now; should be replaced
# with something parameterized, but jar doesn't understand ..)
CLASSES = $(PATH_PREFIX)/*.class $(PATH_PREFIX)/regexp/*.class \
org/mozilla/classfile/*.class
# A class or set of classes as visible from the top level. For want
# of ${subst ,,}. This variable is only used to trigger dependency
# analysis, and multiple words confuse gmake, so it can be smaller
# than the full set of sources. (We assume we'll never need to do the
# same thing with RESOURCES.)
TLCLASS = $(CLASSDIR)/$(PATH_PREFIX)/*.class
# An empty file, used mainly for timestamp/dependency purposes by
# "fast" builds
FASTTARGET=$(CLASSDIR)/.lastbuild
$(JAR) : $(TLCLASS) $(CLASSDIR)/$(RESOURCES)
cd $(CLASSDIR) ; \
jar cf ../$(JAR) $(CLASSES) $(RESOURCES)
$(TLCLASS) : $(SOURCES)
- mkdir -p $(CLASSDIR)
echo "" > $(FASTTARGET)
$(JAVAC) $(JFLAGS) -d $(CLASSDIR) $(SOURCES)
$(CLASSDIR)/$(RESOURCES) : $(RESOURCES)
- mkdir -p $(CLASSDIR)/$(RESOURCEDIR)
cp $(RESOURCES) $(CLASSDIR)/$(RESOURCEDIR)
# Since the jar file is a target for regular builds, "fast" builds use a
# dummy file, updated before each compilation to provide a timestamp.
# Even so, using a dummy file is far from foolproof, so we still need
# the regular build.
fast: $(FASTTARGET)
# So that we recompile only the files that have changed, we pretend
# the only real dependencies are the source files, and recopy the
# resources every time. Right now (14 Jun 99), the only resource is
# Messages.properties, so it's a small price to pay.
$(FASTTARGET) : $(SOURCES)
- mkdir -p $(CLASSDIR)/$(RESOURCEDIR)
cp $(RESOURCES) $(CLASSDIR)/$(RESOURCEDIR)
echo "" > $(FASTTARGET)
$(JAVAC) $(JFLAGS) -d $(CLASSDIR) $(?)
cd $(CLASSDIR) ; \
jar cf ../$(JAR) $(CLASSES) $(RESOURCES)
clean :
- cd $(CLASSDIR) && rm $(CLASSES) $(RESOURCES)
- rm $(PATH_PREFIX)/message.ids \
$(PATH_PREFIX)/property.ids \
$(PATH_PREFIX)/MANIFEST
clobber : clean
-rm $(JAR)
$(PATH_PREFIX)/MANIFEST : $(SOURCES) $(RESOURCES) $(PATH_PREFIX)/Makefile
ls $(SOURCES) $(RESOURCES) $(PATH_PREFIX)/Makefile \
> $(@)
# A sed/grep regular expression.
MESSAGE_PREFIX = msg\.
# Find all the msg.* strings in the source, and condense them to a sorted list,
# excluding duplicates.
# We cheat here and also look at messages in the optimizer subdir.
# (regexp subdir sources are already included in $(SOURCES)
MORE_SOURCES = $(SOURCES) $(PATH_PREFIX)/optimizer/*.java
$(PATH_PREFIX)/message.ids : $(SOURCES)
grep '$(MESSAGE_PREFIX)' $(MORE_SOURCES) |\
sed -e 's/.*\"\($(MESSAGE_PREFIX)\)\([^\"]*\).*/\1\2/' | \
sort | uniq > $(PATH_PREFIX)/message.ids
# Find all the msg.* strings in the resource files, and condense them to a
# sorted list, not excluding duplicates.
$(PATH_PREFIX)/property.ids : $(RESOURCES)
grep '^$(MESSAGE_PREFIX)' $(RESOURCES) |\
sed -e 's/.*\($(MESSAGE_PREFIX)\)\([^ =]*\).*/\1\2/' |\
sort > $(PATH_PREFIX)/property.ids
# Compare the resulting message.ids and property.ids files and confirm
# that they do not differ. This means that every message string used
# in the source is defined somewhere in the resource file, every
# resource in the resource file is used somewhere in the source, and
# no resource is defined more than once.
check : $(PATH_PREFIX)/message.ids $(PATH_PREFIX)/property.ids FORCE
- diff $(PATH_PREFIX)/message.ids $(PATH_PREFIX)/property.ids
# look for unmatched single quotes ... seems to fail when none!
# - sed -e s/\'\'//g $($RESOURCES) | grep \'
# Emulate .PHONY
FORCE :

View File

@@ -0,0 +1,921 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
package org.mozilla.javascript;
import java.util.Hashtable;
/**
* This class implements the Array native object.
* @author Norris Boyd
* @author Mike McCabe
*/
public class NativeArray extends ScriptableObject {
/*
* Optimization possibilities and open issues:
* - Long vs. double schizophrenia. I suspect it might be better
* to use double throughout.
* - Most array operations go through getElem or setElem (defined
* in this file) to handle the full 2^32 range; it might be faster
* to have versions of most of the loops in this file for the
* (infinitely more common) case of indices < 2^31.
* - Functions that need a new Array call "new Array" in the
* current scope rather than using a hardwired constructor;
* "Array" could be redefined. It turns out that js calls the
* equivalent of "new Array" in the current scope, except that it
* always gets at least an object back, even when Array == null.
*/
/**
* Zero-parameter constructor: just used to create Array.prototype
*/
public NativeArray() {
dense = null;
this.length = 0;
}
public NativeArray(long length) {
int intLength = (int) length;
if (intLength == length && intLength > 0) {
if (intLength > maximumDenseLength)
intLength = maximumDenseLength;
dense = new Object[intLength];
for (int i=0; i < intLength; i++)
dense[i] = NOT_FOUND;
}
this.length = length;
}
public NativeArray(Object[] array) {
dense = array;
this.length = array.length;
}
public static void finishInit(Scriptable scope, FunctionObject ctor,
Scriptable proto)
{
// Set some method length values.
// See comment for NativeString.finishInit()
String[] specialLengthNames = { "reverse",
"toString",
};
short[] specialLengthValues = { 0,
0,
};
for (int i=0; i < specialLengthNames.length; i++) {
Object obj = proto.get(specialLengthNames[i], proto);
((FunctionObject) obj).setLength(specialLengthValues[i]);
}
}
public String getClassName() {
return "Array";
}
public Object get(int index, Scriptable start) {
if (dense != null && 0 <= index && index < dense.length)
return dense[index];
return super.get(index, start);
}
public boolean has(int index, Scriptable start) {
if (dense != null && 0 <= index && index < dense.length)
return dense[index] != NOT_FOUND;
return super.has(index, start);
}
public void put(String id, Scriptable start, Object value) {
// only set the array length if given an array index (ECMA 15.4.0)
// try to get an array index from id
double d = ScriptRuntime.toNumber(id);
if (ScriptRuntime.toUint32(d) == d &&
ScriptRuntime.numberToString(d, 10).equals(id) &&
this.length <= d && d != 4294967295.0)
{
this.length = (long)d + 1;
}
super.put(id, start, value);
}
public void put(int index, Scriptable start, Object value) {
// only set the array length if given an array index (ECMA 15.4.0)
if (this.length <= index) {
// avoid overflowing index!
this.length = (long)index + 1;
}
if (dense != null && 0 <= index && index < dense.length) {
dense[index] = value;
return;
}
super.put(index, start, value);
}
public void delete(int index) {
if (dense != null && 0 <= index && index < dense.length) {
dense[index] = NOT_FOUND;
return;
}
super.delete(index);
}
public Object[] getIds() {
Object[] superIds = super.getIds();
if (dense == null)
return superIds;
int count = 0;
int last = dense.length;
if (last > length)
last = (int) length;
for (int i=last-1; i >= 0; i--) {
if (dense[i] != NOT_FOUND)
count++;
}
count += superIds.length;
Object[] result = new Object[count];
System.arraycopy(superIds, 0, result, 0, superIds.length);
for (int i=last-1; i >= 0; i--) {
if (dense[i] != NOT_FOUND)
result[--count] = new Integer(i);
}
return result;
}
public Object getDefaultValue(Class hint) {
if (hint == ScriptRuntime.NumberClass) {
Context cx = Context.getContext();
if (cx.getLanguageVersion() == Context.VERSION_1_2)
return new Long(length);
}
return super.getDefaultValue(hint);
}
/**
* See ECMA 15.4.1,2
*/
public static Object jsConstructor(Context cx, Object[] args,
Function ctorObj, boolean inNewExpr)
throws JavaScriptException
{
if (!inNewExpr) {
// FunctionObject.construct will set up parent, proto
return ctorObj.construct(cx, ctorObj.getParentScope(), args);
}
if (args.length == 0)
return new NativeArray();
// Only use 1 arg as first element for version 1.2; for
// any other version (including 1.3) follow ECMA and use it as
// a length.
if (args.length == 1 && args[0] instanceof Number &&
cx.getLanguageVersion() != cx.VERSION_1_2)
{
return new NativeArray(ScriptRuntime.toUint32(args[0]));
}
// initialize array with arguments
return new NativeArray(args);
}
private static final int lengthAttr = ScriptableObject.DONTENUM |
ScriptableObject.PERMANENT;
public long jsGet_length() {
return length;
}
public void jsSet_length(Object val) {
/* XXX do we satisfy this?
* 15.4.5.1 [[Put]](P, V):
* 1. Call the [[CanPut]] method of A with name P.
* 2. If Result(1) is false, return.
* ?
*/
long longVal = ScriptRuntime.toUint32(val);
if (longVal < length) {
// remove all properties between longVal and length
if (length - longVal > 0x1000) {
// assume that the representation is sparse
Object[] e = getIds(); // will only find in object itself
for (int i=0; i < e.length; i++) {
if (e[i] instanceof String) {
// > MAXINT will appear as string
String id = (String) e[i];
double d = ScriptRuntime.toNumber(id);
if (d == d && d < length)
delete(id);
continue;
}
int index = ((Number) e[i]).intValue();
if (index >= longVal)
delete(index);
}
} else {
// assume a dense representation
for (long i=longVal; i < length; i++) {
// only delete if defined in the object itself
if (hasElem(this, i))
ScriptRuntime.delete(this, new Long(i));
}
}
}
length = longVal;
}
/* Support for generic Array-ish objects. Most of the Array
* functions try to be generic; anything that has a length
* property is assumed to be an array. hasLengthProperty is
* needed in addition to getLengthProperty, because
* getLengthProperty always succeeds - tries to convert strings, etc.
*/
static double getLengthProperty(Scriptable obj) {
// These will both give numeric lengths within Uint32 range.
if (obj instanceof NativeString)
return (double)((NativeString)obj).jsGet_length();
if (obj instanceof NativeArray)
return (double)((NativeArray)obj).jsGet_length();
return ScriptRuntime.toUint32(ScriptRuntime
.getProp(obj, "length", obj));
}
static boolean hasLengthProperty(Object obj) {
if (!(obj instanceof Scriptable) || obj == Context.getUndefinedValue())
return false;
if (obj instanceof NativeString || obj instanceof NativeArray)
return true;
Scriptable sobj = (Scriptable)obj;
// XXX some confusion as to whether or not to walk to get the length
// property. Pending review of js/[new ecma submission] treatment
// of 'arrayness'.
Object property = ScriptRuntime.getProp(sobj, "length", sobj);
return property instanceof Number;
}
/* Utility functions to encapsulate index > Integer.MAX_VALUE
* handling. Also avoids unnecessary object creation that would
* be necessary to use the general ScriptRuntime.get/setElem
* functions... though this is probably premature optimization.
*/
private static boolean hasElem(Scriptable target, long index) {
return index > Integer.MAX_VALUE
? target.has(Long.toString(index), target)
: target.has((int)index, target);
}
private static Object getElem(Scriptable target, long index) {
if (index > Integer.MAX_VALUE) {
String id = Long.toString(index);
return ScriptRuntime.getElem(target, id, target);
} else {
return ScriptRuntime.getElem(target, (int)index);
}
}
private static void setElem(Scriptable target, long index, Object value) {
if (index > Integer.MAX_VALUE) {
String id = Long.toString(index);
ScriptRuntime.setElem(target, id, value, target);
} else {
ScriptRuntime.setElem(target, (int)index, value);
}
}
public static String jsFunction_toString(Context cx, Scriptable thisObj,
Object[] args, Function funObj)
{
return toStringHelper(cx, thisObj,
cx.getLanguageVersion() == cx.VERSION_1_2);
}
private static String toStringHelper(Context cx, Scriptable thisObj,
boolean toSource)
{
/* It's probably redundant to handle long lengths in this
* function; StringBuffers are limited to 2^31 in java.
*/
long length = (long)getLengthProperty(thisObj);
StringBuffer result = new StringBuffer();
if (cx.iterating == null)
cx.iterating = new Hashtable(31);
boolean iterating = cx.iterating.get(thisObj) == Boolean.TRUE;
// whether to return '4,unquoted,5' or '[4, "quoted", 5]'
String separator;
if (toSource) {
result.append("[");
separator = ", ";
} else {
separator = ",";
}
boolean haslast = false;
long i = 0;
if (!iterating) {
for (i = 0; i < length; i++) {
if (i > 0)
result.append(separator);
Object elem = getElem(thisObj, i);
if (elem == null || elem == Undefined.instance) {
haslast = false;
continue;
}
haslast = true;
if (elem instanceof String) {
if (toSource) {
result.append("\"");
result.append(ScriptRuntime.escapeString
(ScriptRuntime.toString(elem)));
result.append("\"");
} else {
result.append(ScriptRuntime.toString(elem));
}
} else {
/* wrap changes to cx.iterating in a try/finally
* so that the reference always gets removed, and
* we don't leak memory. Good place for weak
* references, if we had them. */
try {
// stop recursion.
cx.iterating.put(thisObj, Boolean.TRUE);
result.append(ScriptRuntime.toString(elem));
} finally {
cx.iterating.remove(thisObj);
}
}
}
}
if (toSource) {
//for [,,].length behavior; we want toString to be symmetric.
if (!haslast && i > 0)
result.append(", ]");
else
result.append("]");
}
return result.toString();
}
/**
* See ECMA 15.4.4.3
*/
public static String jsFunction_join(Context cx, Scriptable thisObj,
Object[] args, Function funObj)
{
StringBuffer result = new StringBuffer();
String separator;
double length = getLengthProperty(thisObj);
// if no args, use "," as separator
if (args.length < 1) {
separator = ",";
} else {
separator = ScriptRuntime.toString(args[0]);
}
for (long i=0; i < length; i++) {
if (i > 0)
result.append(separator);
Object temp = getElem(thisObj, i);
if (temp == null || temp == Undefined.instance)
continue;
result.append(ScriptRuntime.toString(temp));
}
return result.toString();
}
/**
* See ECMA 15.4.4.4
*/
public static Scriptable jsFunction_reverse(Context cx, Scriptable thisObj,
Object[] args, Function funObj)
{
long len = (long)getLengthProperty(thisObj);
long half = len / 2;
for(long i=0; i < half; i++) {
long j = len - i - 1;
Object temp1 = getElem(thisObj, i);
Object temp2 = getElem(thisObj, j);
setElem(thisObj, i, temp2);
setElem(thisObj, j, temp1);
}
return thisObj;
}
/**
* See ECMA 15.4.4.5
*/
public static Scriptable jsFunction_sort(Context cx, Scriptable thisObj,
Object[] args, Function funObj)
throws JavaScriptException
{
long length = (long)getLengthProperty(thisObj);
Object compare;
if (args.length > 0 && Undefined.instance != args[0])
// sort with given compare function
compare = args[0];
else
// sort with default compare
compare = null;
// OPT: Would it make sense to use the extended sort for very small
// arrays?
// Should we use the extended sort function, or the faster one?
if (length >= Integer.MAX_VALUE) {
qsort_extended(cx, compare, thisObj, 0, length - 1);
} else {
// copy the JS array into a working array, so it can be
// sorted cheaply.
Object[] working = new Object[(int)length];
for (int i=0; i<length; i++) {
working[i] = getElem(thisObj, i);
}
qsort(cx, compare, working, 0, (int)length - 1);
// copy the working array back into thisObj
for (int i=0; i<length; i++) {
setElem(thisObj, i, working[i]);
}
}
return thisObj;
}
private static double qsortCompare(Context cx, Object jsCompare, Object x,
Object y)
throws JavaScriptException
{
Object undef = Undefined.instance;
// sort undefined to end
if (undef == x || undef == y) {
if (undef != x)
return -1;
if (undef != y)
return 1;
return 0;
}
if (jsCompare == null) {
// if no compare function supplied, sort lexicographically
String a = ScriptRuntime.toString(x);
String b = ScriptRuntime.toString(y);
return a.compareTo(b);
} else {
// assemble args and call supplied JS compare function
// OPT: put this argument creation in the caller and reuse it.
// XXX what to do when compare function returns NaN? ECMA states
// that it's then not a 'consistent compararison function'... but
// then what do we do? Back out and start over with the generic
// compare function when we see a NaN? Throw an error?
Object[] args = {x, y};
// return ScriptRuntime.toNumber(ScriptRuntime.call(jsCompare, null,
// args));
// for now, just ignore it:
double d = ScriptRuntime.
toNumber(ScriptRuntime.call(cx, jsCompare, null, args));
return (d == d) ? d : 0;
}
}
private static void qsort(Context cx, Object jsCompare, Object[] working,
int lo, int hi)
throws JavaScriptException
{
Object pivot;
int i, j;
int a, b;
while (lo < hi) {
i = lo;
j = hi;
a = i;
pivot = working[a];
while (i < j) {
for(;;) {
b = j;
if (qsortCompare(cx, jsCompare, working[j], pivot) <= 0)
break;
j--;
}
working[a] = working[b];
while (i < j && qsortCompare(cx, jsCompare, working[a],
pivot) <= 0)
{
i++;
a = i;
}
working[b] = working[a];
}
working[a] = pivot;
if (i - lo < hi - i) {
qsort(cx, jsCompare, working, lo, i - 1);
lo = i + 1;
} else {
qsort(cx, jsCompare, working, i + 1, hi);
hi = i - 1;
}
}
}
// A version that knows about long indices and doesn't use
// a working array. Probably will never be used.
private static void qsort_extended(Context cx, Object jsCompare,
Scriptable target, long lo, long hi)
throws JavaScriptException
{
Object pivot;
long i, j;
long a, b;
while (lo < hi) {
i = lo;
j = hi;
a = i;
pivot = getElem(target, a);
while (i < j) {
for(;;) {
b = j;
if (qsortCompare(cx, jsCompare, getElem(target, j),
pivot) <= 0)
break;
j--;
}
setElem(target, a, getElem(target, b));
while (i < j && qsortCompare(cx, jsCompare,
getElem(target, a), pivot) <= 0)
{
i++;
a = i;
}
setElem(target, b, getElem(target, a));
}
setElem(target, a, pivot);
if (i - lo < hi - i) {
qsort_extended(cx, jsCompare, target, lo, i - 1);
lo = i + 1;
} else {
qsort_extended(cx, jsCompare, target, i + 1, hi);
hi = i - 1;
}
}
}
/**
* Non-ECMA methods.
*/
public static Object jsFunction_push(Context cx, Scriptable thisObj,
Object[] args, Function funObj)
{
double length = getLengthProperty(thisObj);
for (int i = 0; i < args.length; i++) {
setElem(thisObj, (long)length + i, args[i]);
}
length += args.length;
ScriptRuntime.setProp(thisObj, "length", new Double(length), thisObj);
/*
* If JS1.2, follow Perl4 by returning the last thing pushed.
* Otherwise, return the new array length.
*/
if (cx.getLanguageVersion() == Context.VERSION_1_2)
// if JS1.2 && no arguments, return undefined.
return args.length == 0
? Context.getUndefinedValue()
: args[args.length - 1];
else
return new Long((long)length);
}
public static Object jsFunction_pop(Context cx, Scriptable thisObj,
Object[] args, Function funObj)
{
Object result;
double length = getLengthProperty(thisObj);
if (length > 0) {
length--;
// Get the to-be-deleted property's value.
result = getElem(thisObj, (long)length);
// We don't need to delete the last property, because
// setLength does that for us.
} else {
result = Context.getUndefinedValue();
}
// necessary to match js even when length < 0; js pop will give a
// length property to any target it is called on.
ScriptRuntime.setProp(thisObj, "length", new Double(length), thisObj);
return result;
}
public static Object jsFunction_shift(Context cx, Scriptable thisObj,
Object[] args, Function funOjb)
{
Object result;
double length = getLengthProperty(thisObj);
if (length > 0) {
long i = 0;
length--;
// Get the to-be-deleted property's value.
result = getElem(thisObj, i);
/*
* Slide down the array above the first element. Leave i
* set to point to the last element.
*/
if (length > 0) {
for (i = 1; i <= length; i++) {
Object temp = getElem(thisObj, i);
setElem(thisObj, i - 1, temp);
}
}
// We don't need to delete the last property, because
// setLength does that for us.
} else {
result = Context.getUndefinedValue();
}
ScriptRuntime.setProp(thisObj, "length", new Double(length), thisObj);
return result;
}
public static Object jsFunction_unshift(Context cx, Scriptable thisObj,
Object[] args, Function funOjb)
{
Object result;
double length = (double)getLengthProperty(thisObj);
int argc = args.length;
if (args.length > 0) {
/* Slide up the array to make room for args at the bottom */
if (length > 0) {
for (long last = (long)length - 1; last >= 0; last--) {
Object temp = getElem(thisObj, last);
setElem(thisObj, last + argc, temp);
}
}
/* Copy from argv to the bottom of the array. */
for (int i = 0; i < args.length; i++) {
setElem(thisObj, i, args[i]);
}
/* Follow Perl by returning the new array length. */
length += args.length;
ScriptRuntime.setProp(thisObj, "length",
new Double(length), thisObj);
}
return new Long((long)length);
}
public static Object jsFunction_splice(Context cx, Scriptable thisObj,
Object[] args, Function funObj)
{
/* create an empty Array to return. */
Scriptable scope = getTopLevelScope(funObj);
Object result = ScriptRuntime.newObject(cx, scope, "Array", null);
int argc = args.length;
if (argc == 0)
return result;
double length = getLengthProperty(thisObj);
/* Convert the first argument into a starting index. */
double begin = ScriptRuntime.toInteger(args[0]);
double end;
double delta;
double count;
if (begin < 0) {
begin += length;
if (begin < 0)
begin = 0;
} else if (begin > length) {
begin = length;
}
argc--;
/* Convert the second argument from a count into a fencepost index. */
delta = length - begin;
if (args.length == 1) {
count = delta;
end = length;
} else {
count = ScriptRuntime.toInteger(args[1]);
if (count < 0)
count = 0;
else if (count > delta)
count = delta;
end = begin + count;
argc--;
}
long lbegin = (long)begin;
long lend = (long)end;
/* If there are elements to remove, put them into the return value. */
if (count > 0) {
if (count == 1
&& (cx.getLanguageVersion() == Context.VERSION_1_2))
{
/*
* JS lacks "list context", whereby in Perl one turns the
* single scalar that's spliced out into an array just by
* assigning it to @single instead of $single, or by using it
* as Perl push's first argument, for instance.
*
* JS1.2 emulated Perl too closely and returned a non-Array for
* the single-splice-out case, requiring callers to test and
* wrap in [] if necessary. So JS1.3, default, and other
* versions all return an array of length 1 for uniformity.
*/
result = getElem(thisObj, lbegin);
} else {
for (long last = lbegin; last < lend; last++) {
Scriptable resultArray = (Scriptable)result;
Object temp = getElem(thisObj, last);
setElem(resultArray, last - lbegin, temp);
}
}
} else if (count == 0
&& cx.getLanguageVersion() == Context.VERSION_1_2)
{
/* Emulate C JS1.2; if no elements are removed, return undefined. */
result = Context.getUndefinedValue();
}
/* Find the direction (up or down) to copy and make way for argv. */
delta = argc - count;
if (delta > 0) {
for (long last = (long)length - 1; last >= lend; last--) {
Object temp = getElem(thisObj, last);
setElem(thisObj, last + (long)delta, temp);
}
} else if (delta < 0) {
for (long last = lend; last < length; last++) {
Object temp = getElem(thisObj, last);
setElem(thisObj, last + (long)delta, temp);
}
}
/* Copy from argv into the hole to complete the splice. */
int argoffset = args.length - argc;
for (int i = 0; i < argc; i++) {
setElem(thisObj, lbegin + i, args[i + argoffset]);
}
/* Update length in case we deleted elements from the end. */
ScriptRuntime.setProp(thisObj, "length",
new Double(length + delta), thisObj);
return result;
}
/*
* Python-esque sequence operations.
*/
public static Scriptable jsFunction_concat(Context cx, Scriptable thisObj,
Object[] args, Function funObj)
{
/* Concat tries to keep the definition of an array as general
* as possible; if it finds that an object has a numeric
* 'length' property, then it treats that object as an array.
* This treats string atoms and string objects differently; as
* string objects have a length property and are accessible by
* index, they get exploded into arrays when added, while
* atomic strings are just added as strings.
*/
// create an empty Array to return.
Scriptable scope = getTopLevelScope(funObj);
Scriptable result = ScriptRuntime.newObject(cx, scope, "Array", null);
double length;
long slot = 0;
/* Put the target in the result array; only add it as an array
* if it looks like one.
*/
if (hasLengthProperty(thisObj)) {
length = getLengthProperty(thisObj);
// Copy from the target object into the result
for (slot = 0; slot < length; slot++) {
Object temp = getElem(thisObj, slot);
setElem(result, slot, temp);
}
} else {
setElem(result, slot++, thisObj);
}
/* Copy from the arguments into the result. If any argument
* has a numeric length property, treat it as an array and add
* elements separately; otherwise, just copy the argument.
*/
for (int i = 0; i < args.length; i++) {
if (hasLengthProperty(args[i])) {
// hasLengthProperty => instanceOf Scriptable.
Scriptable arg = (Scriptable)args[i];
length = getLengthProperty(arg);
for (long j = 0; j < length; j++, slot++) {
Object temp = getElem(arg, j);
setElem(result, slot, temp);
}
} else {
setElem(result, slot++, args[i]);
}
}
return result;
}
public static Scriptable jsFunction_slice(Context cx, Scriptable thisObj,
Object[] args, Function funObj)
{
Scriptable scope = getTopLevelScope(funObj);
Scriptable result = ScriptRuntime.newObject(cx, scope, "Array", null);
double length = getLengthProperty(thisObj);
double begin = 0;
double end = length;
if (args.length > 0) {
begin = ScriptRuntime.toInteger(args[0]);
if (begin < 0) {
begin += length;
if (begin < 0)
begin = 0;
} else if (begin > length) {
begin = length;
}
if (args.length > 1) {
end = ScriptRuntime.toInteger(args[1]);
if (end < 0) {
end += length;
if (end < 0)
end = 0;
} else if (end > length) {
end = length;
}
}
}
long lbegin = (long)begin;
long lend = (long)end;
for (long slot = lbegin; slot < lend; slot++) {
Object temp = getElem(thisObj, slot);
setElem(result, slot - lbegin, temp);
}
return result;
}
private long length;
private Object[] dense;
private static final int maximumDenseLength = 10000;
}

View File

@@ -0,0 +1,74 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
package org.mozilla.javascript;
/**
* This class implements the Boolean native object.
* See ECMA 15.6.
* @author Norris Boyd
*/
public class NativeBoolean extends ScriptableObject {
/**
* Zero-parameter constructor: just used to create Boolean.prototype
*/
public NativeBoolean() {
}
public NativeBoolean(boolean b) {
booleanValue = b;
}
public String getClassName() {
return "Boolean";
}
public Object getDefaultValue(Class typeHint) {
// This is actually non-ECMA, but will be proposed
// as a change in round 2.
if (typeHint == ScriptRuntime.BooleanClass)
return booleanValue ? Boolean.TRUE : Boolean.FALSE;
return super.getDefaultValue(typeHint);
}
public static Object jsConstructor(Context cx, Object[] args,
Function ctorObj, boolean inNewExpr)
{
boolean b = args.length >= 1
? ScriptRuntime.toBoolean(args[0])
: false;
if (inNewExpr) {
// new Boolean(val) creates a new boolean object.
return new NativeBoolean(b);
}
// Boolean(val) converts val to a boolean.
return b ? Boolean.TRUE : Boolean.FALSE;
}
public String jsFunction_toString() {
return booleanValue ? "true" : "false";
}
public boolean jsFunction_valueOf() {
return booleanValue;
}
private boolean booleanValue;
}

View File

@@ -0,0 +1,128 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
package org.mozilla.javascript;
/**
* This class implements the activation object.
*
* See ECMA 10.1.6
*
* @see org.mozilla.javascript.Arguments
* @author Norris Boyd
*/
public final class NativeCall extends ScriptableObject {
NativeCall(Context cx, Scriptable scope, NativeFunction funObj,
Scriptable thisObj, Object[] args)
{
this(cx, scope, funObj, thisObj);
this.originalArgs = args;
// initialize references to nested functions
NativeFunction[] fns = funObj.nestedFunctions;
if (fns != null) {
for (int i=0; i < fns.length; i++) {
NativeFunction f = fns[i];
if (f.names != null)
super.put(f.names[0], this, f);
}
}
// initialize values of arguments
String[] names = funObj.names;
if (names != null) {
for (int i=0; i < funObj.argCount; i++) {
Object val = i < args.length ? args[i]
: Undefined.instance;
super.put(names[i+1], this, val);
}
}
// initialize "arguments" property
super.put("arguments", this, new Arguments(this));
}
NativeCall(Context cx, Scriptable scope, NativeFunction funObj,
Scriptable thisObj)
{
this.funObj = funObj;
this.thisObj = thisObj;
setParentScope(scope);
// leave prototype null
// save current activation
this.caller = cx.currentActivation;
cx.currentActivation = this;
}
// Needed in order to use this class with ScriptableObject.defineClass
public NativeCall() {
}
public String getClassName() {
return "Call";
}
public static Object jsConstructor(Context cx, Object[] args,
Function ctorObj, boolean inNewExpr)
{
if (!inNewExpr) {
Object[] errArgs = { "Call" };
throw Context.reportRuntimeError(Context.getMessage
("msg.only.from.new", errArgs));
}
ScriptRuntime.checkDeprecated(cx, "Call");
NativeCall result = new NativeCall();
result.setPrototype(getObjectPrototype(ctorObj));
return result;
}
NativeCall getActivation(NativeFunction f) {
NativeCall x = this;
do {
if (x.funObj == f)
return x;
x = x.caller;
} while (x != null);
return null;
}
public NativeFunction getFunctionObject() {
return funObj;
}
public Object[] getOriginalArguments() {
return originalArgs;
}
public NativeCall getCaller() {
return caller;
}
public Scriptable getThisObj() {
return thisObj;
}
NativeCall caller;
NativeFunction funObj;
Scriptable thisObj;
Object[] originalArgs;
public int debugPC;
}

View File

@@ -0,0 +1,103 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
package org.mozilla.javascript;
/**
* This class implements the closure object.
*
* @author Norris Boyd
*/
public class NativeClosure extends ScriptableObject implements Function {
public NativeClosure() {
}
public NativeClosure(Context cx, Scriptable scope, NativeFunction f) {
setPrototype(f);
setParentScope(scope);
String name = f.names != null ? f.names[0] : "";
if (name != null && name.length() > 0) {
scope.put(name, scope, scope.getParentScope() == null
? (Object) f : this);
}
}
public String getClassName() {
return "Closure";
}
public Object getDefaultValue(Class typeHint) {
if (typeHint == ScriptRuntime.FunctionClass)
return prototype;
return super.getDefaultValue(typeHint);
}
public Object call(Context cx, Scriptable scope, Scriptable thisObj,
Object[] args)
throws JavaScriptException
{
Function proto = checkProto();
return proto.call(cx, getParentScope(), thisObj, args);
}
public Scriptable construct(Context cx, Scriptable scope, Object[] args)
throws JavaScriptException
{
Function proto = checkProto();
return proto.construct(cx, getParentScope(), args);
}
public static Object jsConstructor(Context cx, Object[] args,
Function ctorObj, boolean inNewExpr)
{
Object[] msgArgs = { "Closure" };
throw Context.reportRuntimeError(
Context.getMessage("msg.cant.call.indirect", msgArgs));
}
public static Object newClosureSpecial(Context cx, Scriptable varObj,
Object[] args, Function ctorObj)
{
ScriptRuntime.checkDeprecated(cx, "Closure");
NativeFunction f = args.length > 0 &&
args[0] instanceof NativeFunction
? (NativeFunction) args[0]
: null;
NativeClosure result = f != null
? new NativeClosure(cx, varObj, f)
: new NativeClosure();
Scriptable scope = getTopLevelScope(ctorObj);
result.setPrototype(args.length == 0
? getObjectPrototype(scope)
: ScriptRuntime.toObject(scope, args[0]));
result.setParentScope(varObj);
return result;
}
private Function checkProto() {
Scriptable proto = getPrototype();
if (!(proto instanceof Function)) {
throw Context.reportRuntimeError(Context.getMessage
("msg.closure.proto", null));
}
return (Function) proto;
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,403 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
package org.mozilla.javascript;
import java.io.StringReader;
import java.io.IOException;
/**
* This class implements the global native object (function and value
* properties only).
*
* See ECMA 15.1.[12].
*
* @author Mike Shaver
*/
public class NativeGlobal {
public static void init(Scriptable scope)
throws PropertyException
{
String names[] = { "eval",
"parseInt",
"parseFloat",
"escape",
"unescape",
"isNaN",
"isFinite"
};
// We can downcast here because Context.initStandardObjects
// takes a ScriptableObject scope.
ScriptableObject global = (ScriptableObject) scope;
global.defineFunctionProperties(names, NativeGlobal.class,
ScriptableObject.DONTENUM);
global.defineProperty("NaN", ScriptRuntime.NaNobj,
ScriptableObject.DONTENUM);
global.defineProperty("Infinity", new Double(Double.POSITIVE_INFINITY),
ScriptableObject.DONTENUM);
global.defineProperty("undefined", Undefined.instance,
ScriptableObject.DONTENUM);
}
/**
* The global method parseInt, as per ECMA-262 15.1.2.2.
*/
public static Object parseInt(String s, int radix) {
int len = s.length();
if (len == 0)
return ScriptRuntime.NaNobj;
boolean negative = false;
int start = 0;
char c;
do {
c = s.charAt(start);
if (!Character.isWhitespace(c))
break;
start++;
} while (start < len);
if (c == '+' || (negative = (c == '-')))
start++;
final int NO_RADIX = -1;
if (radix == 0) {
radix = NO_RADIX;
} else if (radix < 2 || radix > 36) {
return ScriptRuntime.NaNobj;
} else if (radix == 16 && len - start > 1 &&
s.charAt(start) == '0')
{
c = s.charAt(start+1);
if (c == 'x' || c == 'X')
start += 2;
}
if (radix == NO_RADIX) {
radix = 10;
if (len - start > 1 && s.charAt(start) == '0') {
c = s.charAt(start+1);
if (c == 'x' || c == 'X') {
radix = 16;
start += 2;
} else if (c != '.') {
radix = 8;
start++;
}
}
}
double d = ScriptRuntime.stringToNumber(s, start, radix);
return new Double(negative ? -d : d);
}
/**
* The global method parseFloat, as per ECMA-262 15.1.2.3.
*
* @param cx unused
* @param thisObj unused
* @param args the arguments to parseFloat, ignoring args[>=1]
* @param funObj unused
*/
public static Object parseFloat(Context cx, Scriptable thisObj,
Object[] args, Function funObj)
{
if (args.length < 1)
return ScriptRuntime.NaNobj;
String s = ScriptRuntime.toString(args[0]);
int len = s.length();
if (len == 0)
return ScriptRuntime.NaNobj;
int i;
char c;
// Scan forward to the first digit or .
for (i=0; TokenStream.isJSSpace(c = s.charAt(i)) && i+1 < len; i++)
/* empty */
;
int start = i;
if (c == '+' || c == '-')
c = s.charAt(++i);
if (c == 'I') {
// check for "Infinity"
double d;
if (i+8 <= len && s.substring(i, i+8).equals("Infinity"))
d = s.charAt(start) == '-' ? Double.NEGATIVE_INFINITY
: Double.POSITIVE_INFINITY;
else
return ScriptRuntime.NaNobj;
return new Double(d);
}
// Find the end of the legal bit
int decimal = -1;
int exponent = -1;
for (; i < len; i++) {
switch (s.charAt(i)) {
case '.':
if (decimal != -1) // Only allow a single decimal point.
break;
decimal = i;
continue;
case 'e':
case 'E':
if (exponent != -1)
break;
exponent = i;
continue;
case '+':
case '-':
// Only allow '+' or '-' after 'e' or 'E'
if (exponent != i-1)
break;
continue;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
continue;
default:
break;
}
break;
}
s = s.substring(start, i);
try {
return Double.valueOf(s);
}
catch (NumberFormatException ex) {
return ScriptRuntime.NaNobj;
}
}
/**
* The global method escape, as per ECMA-262 15.1.2.4.
* Includes code for the 'mask' argument supported by the C escape
* method, which used to be part of the browser imbedding. Blame
* for the strange constant names should be directed there.
*/
private static int
URL_XALPHAS = 1,
URL_XPALPHAS = 2,
URL_PATH = 4;
public static Object escape(Context cx, Scriptable thisObj,
Object[] args, Function funObj)
{
char digits[] = {'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
if (args.length < 1)
args = ScriptRuntime.padArguments(args, 1);
String s = ScriptRuntime.toString(args[0]);
int mask = URL_XALPHAS | URL_XPALPHAS | URL_PATH;
if (args.length > 1) { // the 'mask' argument. Non-ECMA.
double d = ScriptRuntime.toNumber(args[1]);
if (d != d || ((mask = (int) d) != d) ||
0 != (mask & ~(URL_XALPHAS | URL_XPALPHAS | URL_PATH)))
{
String message = Context.getMessage
("msg.bad.esc.mask", null);
cx.reportError(message);
// do the ecma thing, in case reportError returns.
mask = URL_XALPHAS | URL_XPALPHAS | URL_PATH;
}
}
StringBuffer R = new StringBuffer();
for (int k = 0; k < s.length(); k++) {
char c = s.charAt(k);
if (mask != 0 &&
((c >= '0' && c <= '9') ||
(c >= 'A' && c <= 'Z') ||
(c >= 'a' && c <= 'z') ||
c == '@' || c == '*' || c == '_' ||
c == '-' || c == '.' ||
((c == '/' || c == '+') && mask > 3)))
R.append(c);
else if (c < 256) {
if (c == ' ' && mask == URL_XPALPHAS) {
R.append('+');
} else {
R.append('%');
R.append(digits[c >> 4]);
R.append(digits[c & 0xF]);
}
} else {
R.append('%');
R.append('u');
R.append(digits[c >> 12]);
R.append(digits[(c & 0xF00) >> 8]);
R.append(digits[(c & 0xF0) >> 4]);
R.append(digits[c & 0xF]);
}
}
return R.toString();
}
/**
* The global unescape method, as per ECMA-262 15.1.2.5.
*/
public static Object unescape(Context cx, Scriptable thisObj,
Object[] args, Function funObj)
{
if (args.length < 1)
args = ScriptRuntime.padArguments(args, 1);
String s = ScriptRuntime.toString(args[0]);
StringBuffer R = new StringBuffer();
stringIter: for (int k = 0; k < s.length(); k++) {
char c = s.charAt(k);
if (c != '%' || k == s.length() -1) {
R.append(c);
continue;
}
String hex;
int end, start;
if (s.charAt(k+1) == 'u') {
start = k+2;
end = k+6;
} else {
start = k+1;
end = k+3;
}
if (end > s.length()) {
R.append('%');
continue;
}
hex = s.substring(start, end);
for (int i = 0; i < hex.length(); i++)
if (!TokenStream.isXDigit(hex.charAt(i))) {
R.append('%');
continue stringIter;
}
k = end - 1;
R.append((new Character((char) Integer.valueOf(hex, 16).intValue())));
}
return R.toString();
}
/**
* The global method isNaN, as per ECMA-262 15.1.2.6.
*/
public static Object isNaN(Context cx, Scriptable thisObj,
Object[] args, Function funObj)
{
if (args.length < 1)
return Boolean.TRUE;
double d = ScriptRuntime.toNumber(args[0]);
return (d != d) ? Boolean.TRUE : Boolean.FALSE;
}
public static Object isFinite(Context cx, Scriptable thisObj,
Object[] args, Function funObj)
{
if (args.length < 1)
return Boolean.FALSE;
double d = ScriptRuntime.toNumber(args[0]);
return (d != d || d == Double.POSITIVE_INFINITY ||
d == Double.NEGATIVE_INFINITY)
? Boolean.FALSE
: Boolean.TRUE;
}
public static Object eval(Context cx, Scriptable thisObj,
Object[] args, Function funObj)
throws JavaScriptException
{
Object[] msgArgs = { "eval" };
throw Context.reportRuntimeError(
Context.getMessage("msg.cant.call.indirect", msgArgs));
}
/**
* The eval function property of the global object.
*
* See ECMA 15.1.2.1
*/
public static Object evalSpecial(Context cx, Scriptable scope,
Object thisArg, Object[] args,
String filename, int lineNumber)
throws JavaScriptException
{
if (args.length < 1)
return Undefined.instance;
Object x = args[0];
if (!(x instanceof String)) {
String message = Context.getMessage("msg.eval.nonstring", null);
Context.reportWarning(message);
return x;
}
int[] linep = { lineNumber };
if (filename == null) {
filename = Context.getSourcePositionFromStack(linep);
if (filename == null) {
filename = "<eval'ed string>";
linep[0] = 1;
}
}
try {
StringReader in = new StringReader((String) x);
Object securityDomain = cx.getSecurityDomainForStackDepth(3);
// Compile the reader with opt level of -1 to force interpreter
// mode.
int oldOptLevel = cx.getOptimizationLevel();
cx.setOptimizationLevel(-1);
Script script = cx.compileReader(null, in, filename, linep[0],
securityDomain);
cx.setOptimizationLevel(oldOptLevel);
// if the compile fails, an error has been reported by the
// compiler, but we need to stop execution to avoid
// infinite looping on while(true) { eval('foo bar') } -
// so we throw an EvaluatorException.
if (script == null) {
String message = Context.getMessage("msg.syntax", null);
throw new EvaluatorException(message);
}
InterpretedScript is = (InterpretedScript) script;
Object result = is.call(cx, scope, (Scriptable) thisArg, null);
return result;
}
catch (IOException ioe) {
// should never happen since we just made the Reader from a String
throw new RuntimeException("unexpected io exception");
}
}
}

View File

@@ -0,0 +1,129 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
package org.mozilla.javascript;
import java.lang.reflect.Array;
/**
* This class reflects Java arrays into the JavaScript environment.
*
* @author Mike Shaver
* @see NativeJavaClass
* @see NativeJavaObject
* @see NativeJavaPackage
*/
public class NativeJavaArray extends NativeJavaObject {
public String getClassName() {
return "JavaArray";
}
public static NativeJavaArray wrap(Scriptable scope, Object array) {
return new NativeJavaArray(scope, array);
}
public Object unwrap() {
return array;
}
public NativeJavaArray(Scriptable scope, Object array) {
super(scope, null, ScriptRuntime.ObjectClass);
Class cl = array.getClass();
if (!cl.isArray()) {
throw new RuntimeException("Array expected");
}
this.array = array;
this.length = Array.getLength(array);
this.cls = cl.getComponentType();
}
public boolean has(String id, Scriptable start) {
return id.equals("length") || super.has(id, start);
}
public boolean has(int index, Scriptable start) {
return 0 <= index && index < length;
}
public Object get(String id, Scriptable start) {
if (id.equals("length"))
return new Integer(length);
return super.get(id, start);
}
public Object get(int index, Scriptable start) {
if (0 <= index && index < length)
return NativeJavaObject.wrap(this, Array.get(array, index), cls);
return Undefined.instance;
}
public void put(String id, Scriptable start, Object value) {
// Ignore assignments to "length"--it's readonly.
if (!id.equals("length"))
super.put(id, start, value);
}
public void put(int index, Scriptable start, Object value) {
if (0 <= index && index < length) {
Array.set(array, index, NativeJavaObject.coerceType(cls, value));
return;
}
super.put(index, start, value);
}
public Object getDefaultValue(Class hint) {
if (hint == null || hint == ScriptRuntime.StringClass)
return array.toString();
if (hint == ScriptRuntime.BooleanClass)
return Boolean.TRUE;
if (hint == ScriptRuntime.NumberClass)
return ScriptRuntime.NaNobj;
return this;
}
public Object[] getIds() {
Object[] result = new Object[length];
int i = length;
while (--i >= 0)
result[i] = new Integer(i);
return result;
}
public boolean hasInstance(Scriptable value) {
if (!(value instanceof NativeJavaObject))
return false;
Object instance = ((NativeJavaObject)value).unwrap();
return cls.isInstance(instance);
}
public Scriptable getPrototype() {
if (prototype == null) {
prototype =
ScriptableObject.getClassPrototype(this.getParentScope(),
"Array");
}
return prototype;
}
Object array;
int length;
Class cls;
Scriptable prototype;
}

View File

@@ -0,0 +1,243 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
package org.mozilla.javascript;
import java.lang.reflect.*;
import java.util.Hashtable;
/**
* This class reflects Java classes into the JavaScript environment, mainly
* for constructors and static members. We lazily reflect properties,
* and currently do not guarantee that a single j.l.Class is only
* reflected once into the JS environment, although we should.
* The only known case where multiple reflections
* are possible occurs when a j.l.Class is wrapped as part of a
* method return or property access, rather than by walking the
* Packages/java tree.
*
* @author Mike Shaver
* @see NativeJavaArray
* @see NativeJavaObject
* @see NativeJavaPackage
*/
public class NativeJavaClass extends NativeJavaObject implements Function {
public NativeJavaClass(Scriptable scope, Class cl) {
super(scope, cl, JavaMembers.lookupClass(scope, cl, cl));
fieldAndMethods = members.getFieldAndMethodsObjects(javaObject, false);
}
public String getClassName() {
return "JavaClass";
}
public boolean has(String name, Scriptable start) {
return members.has(name, true);
}
public Object get(String name, Scriptable start) {
// When used as a constructor, ScriptRuntime.newObject() asks
// for our prototype to create an object of the correct type.
// We don't really care what the object is, since we're returning
// one constructed out of whole cloth, so we return null.
if (name.equals("prototype"))
return null;
Object result = Scriptable.NOT_FOUND;
if (fieldAndMethods != null) {
result = fieldAndMethods.get(name);
if (result != null)
return result;
}
if (members.has(name, true)) {
result = members.get(this, name, javaObject, true);
} else {
// experimental: look for nested classes by appending $name to current class' name.
try {
String nestedName = getClassObject().getName() + '$' + name;
Class nestedClass = Class.forName(nestedName);
Scriptable nestedValue = wrap(ScriptableObject.getTopLevelScope(this), nestedClass);
nestedValue.setParentScope(this);
result = nestedValue;
} catch (ClassNotFoundException ex) {
throw members.reportMemberNotFound(name);
}
}
return result;
}
public void put(String name, Scriptable start, Object value) {
members.put(name, javaObject, value, true);
}
public Object[] getIds() {
return members.getIds(true);
}
public Class getClassObject() {
return (Class) super.unwrap();
}
// XXX ??
public static NativeJavaClass wrap(Scriptable scope, Class cls) {
return new NativeJavaClass(scope, cls);
}
public Object getDefaultValue(Class hint) {
if (hint == null || hint == ScriptRuntime.StringClass)
return this.toString();
if (hint == ScriptRuntime.BooleanClass)
return Boolean.TRUE;
if (hint == ScriptRuntime.NumberClass)
return ScriptRuntime.NaNobj;
return this;
}
public Object call(Context cx, Scriptable scope, Scriptable thisObj,
Object[] args)
throws JavaScriptException
{
return construct(cx, scope, args);
}
public Scriptable construct(Context cx, Scriptable scope, Object[] args)
throws JavaScriptException
{
Class classObject = getClassObject();
int modifiers = classObject.getModifiers();
if (! (Modifier.isInterface(modifiers) ||
Modifier.isAbstract(modifiers)))
{
Constructor[] ctors = members.getConstructors();
Member member = NativeJavaMethod.findFunction(ctors, args);
Constructor ctor = (Constructor) member;
if (ctor == null) {
String sig = NativeJavaMethod.scriptSignature(args);
Object errArgs[] = { classObject.getName(), sig };
throw Context.reportRuntimeError(Context.getMessage(
"msg.no.java.ctor", errArgs));
}
// Found the constructor, so try invoking it.
return NativeJavaClass.constructSpecific(cx, scope,
this, ctor, args);
} else {
Scriptable topLevel = ScriptableObject.getTopLevelScope(this);
String msg = "";
try {
// trying to construct an interface; use JavaAdapter to
// construct a new class on the fly that implements this
// interface.
Object v = topLevel.get("JavaAdapter", topLevel);
if (v != NOT_FOUND) {
Function f = (Function) v;
Object[] adapterArgs = { this, args[0] };
return (Scriptable) f.construct(cx, topLevel,
adapterArgs);
}
} catch (Exception ex) {
// fall through to error
msg = ex.getMessage();
}
Object[] errArgs = { msg, classObject.getName() };
throw Context.reportRuntimeError(Context.getMessage
("msg.cant.instantiate",
errArgs));
}
}
public static Scriptable constructSpecific(Context cx,
Scriptable scope,
Scriptable thisObj,
Constructor ctor,
Object[] args)
throws JavaScriptException
{
Scriptable topLevel = ScriptableObject.getTopLevelScope(thisObj);
Class classObject = ctor.getDeclaringClass();
Class[] paramTypes = ctor.getParameterTypes();
for (int i = 0; i < args.length; i++) {
args[i] = NativeJavaObject.coerceType(paramTypes[i], args[i]);
}
try {
// we need to force this to be wrapped, because construct _has_
// to return a scriptable
return
(Scriptable) NativeJavaObject.wrap(topLevel,
ctor.newInstance(args),
classObject);
} catch (InstantiationException instEx) {
Object[] errArgs = { instEx.getMessage(),
classObject.getName() };
throw Context.reportRuntimeError(Context.getMessage
("msg.cant.instantiate",
errArgs));
} catch (IllegalArgumentException argEx) {
String signature = NativeJavaMethod.scriptSignature(args);
String ctorString = ctor.toString();
Object[] errArgs = { argEx.getMessage(),ctorString,signature };
throw Context.reportRuntimeError(Context.getMessage
("msg.bad.ctor.sig",
errArgs));
} catch (InvocationTargetException e) {
throw JavaScriptException.wrapException(scope, e);
} catch (IllegalAccessException accessEx) {
Object[] errArgs = { accessEx.getMessage() };
throw Context.reportRuntimeError(Context.getMessage
("msg.java.internal.private", errArgs));
}
}
public String toString() {
return "[JavaClass " + getClassObject().getName() + "]";
}
/**
* Determines if prototype is a wrapped Java object and performs
* a Java "instanceof".
* Exception: if value is an instance of NativeJavaClass, it isn't
* considered an instance of the Java class; this forestalls any
* name conflicts between java.lang.Class's methods and the
* static methods exposed by a JavaNativeClass.
*/
public boolean hasInstance(Scriptable value) {
if (value instanceof NativeJavaObject &&
!(value instanceof NativeJavaClass)) {
Object instance = ((NativeJavaObject)value).unwrap();
return getClassObject().isInstance(instance);
}
// value wasn't something we understand
return false;
}
private Hashtable fieldAndMethods;
// beard: need a scope for finding top-level prototypes.
private Scriptable parent;
}

View File

@@ -0,0 +1,81 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
package org.mozilla.javascript;
import java.lang.reflect.*;
/**
* This class reflects a single Java constructor into the JavaScript
* environment. It satisfies a request for an overloaded constructor,
* as introduced in LiveConnect 3.
* All NativeJavaConstructors behave as JSRef `bound' methods, in that they
* always construct the same NativeJavaClass regardless of any reparenting
* that may occur.
*
* @author Frank Mitchell
* @see NativeJavaMethod
* @see NativeJavaPackage
* @see NativeJavaClass
*/
public class NativeJavaConstructor extends NativeFunction implements Function {
public NativeJavaConstructor(Constructor ctor) {
this.constructor = ctor;
names = new String[1];
names[0] = "<init>" + NativeJavaMethod.signature(ctor);
}
public Object call(Context cx, Scriptable scope, Scriptable thisObj,
Object[] args)
throws JavaScriptException
{
// Find a method that matches the types given.
if (constructor == null) {
throw new RuntimeException("No constructor defined for call");
}
// Eliminate useless args[0] and unwrap if required
for (int i = 0; i < args.length; i++) {
if (args[i] instanceof Wrapper) {
args[i] = ((Wrapper)args[i]).unwrap();
}
}
return NativeJavaClass.constructSpecific(cx, scope,
this, constructor, args);
}
/*
public Object getDefaultValue(Class hint) {
return this;
}
*/
public String toString() {
return "[JavaConstructor " + constructor.getName() + "]";
}
Constructor getConstructor() {
return constructor;
}
Constructor constructor;
}

View File

@@ -0,0 +1,465 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
package org.mozilla.javascript;
import java.lang.reflect.*;
/**
* This class reflects Java methods into the JavaScript environment. It
* handles overloading of methods, and method/field name conflicts.
* All NativeJavaMethods behave as JSRef `bound' methods, in that they
* always operate on the object underlying the original NativeJavaObject
* parent regardless of any reparenting that may occur.
*
* @author Mike Shaver
* @see NativeJavaArray
* @see NativeJavaPackage
* @see NativeJavaClass
*/
public class NativeJavaMethod extends NativeFunction implements Function {
public NativeJavaMethod() {
names = new String[1];
}
public NativeJavaMethod(Method[] methods) {
this.methods = methods;
names = new String[1];
names[0] = methods[0].getName();
}
public NativeJavaMethod(Method method, String name) {
this.methods = new Method[1];
this.methods[0] = method;
names = new String[1];
names[0] = name;
}
public void add(Method method) {
if (names[0] == null) {
names[0] = method.getName();
} else if (!names[0].equals(method.getName())) {
throw new RuntimeException("internal method name mismatch");
}
// XXX a more intelligent growth algorithm would be nice
int len = methods == null ? 0 : methods.length;
Method[] newMeths = new Method[len + 1];
for (int i = 0; i < len; i++)
newMeths[i] = methods[i];
newMeths[len] = method;
methods = newMeths;
}
static String scriptSignature(Object value) {
if (value == null) {
return "null";
}
else {
Class type = value.getClass();
if (type == ScriptRuntime.UndefinedClass)
return "undefined";
if (type == ScriptRuntime.BooleanClass)
return "boolean";
if (type == ScriptRuntime.StringClass)
return "string";
if (ScriptRuntime.NumberClass.isAssignableFrom(type))
return "number";
if (value instanceof NativeJavaObject) {
return ((NativeJavaObject)value).unwrap().getClass().getName();
}
if (value instanceof Scriptable) {
if (value instanceof Function)
return "function";
return "object";
}
return javaSignature(type);
}
}
static String scriptSignature(Object[] values) {
StringBuffer sig = new StringBuffer();
for (int i = 0; i < values.length; i++) {
if (i != 0)
sig.append(',');
sig.append(scriptSignature(values[i]));
}
return sig.toString();
}
static String javaSignature(Class type) {
if (type == null) {
return "null";
}
else if (type.isArray()) {
return javaSignature(type.getComponentType()) + "[]";
}
return type.getName();
}
static String javaSignature(Class[] types) {
StringBuffer sig = new StringBuffer();
for (int i = 0; i < types.length; i++) {
if (i != 0)
sig.append(',');
sig.append(javaSignature(types[i]));
}
return sig.toString();
}
static String signature(Member member) {
Class paramTypes[];
if (member instanceof Method) {
paramTypes = ((Method) member).getParameterTypes();
return member.getName() + "(" + javaSignature(paramTypes) + ")";
}
else {
paramTypes = ((Constructor) member).getParameterTypes();
return "(" + javaSignature(paramTypes) + ")";
}
}
public Object call(Context cx, Scriptable scope, Scriptable thisObj,
Object[] args)
throws JavaScriptException
{
// Find a method that matches the types given.
if (methods.length == 0) {
throw new RuntimeException("No methods defined for call");
}
Method meth = (Method) findFunction(methods, args);
if (meth == null) {
Class c = methods[0].getDeclaringClass();
String sig = c.getName() + "." + names[0] + "(" +
scriptSignature(args) + ")";
Object errArgs[] = { sig };
throw Context.reportRuntimeError(
Context.getMessage("msg.java.no_such_method", errArgs));
}
// OPT: already retrieved in findFunction, so we should inline that
// OPT: or pass it back somehow
Class paramTypes[] = meth.getParameterTypes();
// First, we marshall the args.
for (int i = 0; i < args.length; i++) {
args[i] = NativeJavaObject.coerceType(paramTypes[i], args[i]);
}
Object javaObject;
try {
javaObject = ((NativeJavaObject) thisObj).unwrap();
}
catch (ClassCastException e) {
if (Modifier.isStatic(meth.getModifiers())) {
javaObject = null; // don't need it anyway
} else {
Object errArgs[] = { names[0] };
throw Context.reportRuntimeError(
Context.getMessage("msg.nonjava.method", errArgs));
}
}
try {
if (debug) {
printDebug("Calling", meth, args);
}
Object retval = meth.invoke(javaObject, args);
Class staticType = meth.getReturnType();
if (debug) {
Class actualType = (retval == null) ? null : retval.getClass();
System.err.println(" ----- Returned " + retval +
" actual = " + actualType +
" expect = " + staticType);
}
Object wrapped = NativeJavaObject.wrap(scope, retval, staticType);
if (debug) {
Class actualType = (wrapped == null) ? null : wrapped.getClass();
System.err.println(" ----- Wrapped as " + wrapped +
" class = " + actualType);
}
// XXX set prototype && parent
if (wrapped == Undefined.instance)
return wrapped;
if (wrapped == null && staticType == Void.TYPE)
return Undefined.instance;
if (retval != wrapped && wrapped instanceof Scriptable) {
Scriptable s = (Scriptable)wrapped;
if (s.getPrototype() == null)
s.setPrototype(parent.getPrototype());
if (s.getParentScope() == null)
s.setParentScope(parent.getParentScope());
}
return wrapped;
} catch (IllegalAccessException accessEx) {
throw Context.reportRuntimeError(accessEx.getMessage());
} catch (InvocationTargetException e) {
throw JavaScriptException.wrapException(scope, e);
}
}
/**
* Find the correct function to call given the set of methods
* or constructors and the arguments.
* If no function can be found to call, return null.
*/
static Member findFunction(Member[] methodsOrCtors, Object[] args) {
if (methodsOrCtors.length == 0)
return null;
boolean hasMethods = methodsOrCtors[0] instanceof Method;
if (Context.useJSObject &&
NativeJavaObject.jsObjectClass != null)
{
try {
for (int i = 0; i < args.length; i++) {
if (NativeJavaObject.jsObjectClass.isInstance(args[i]))
args[i] = NativeJavaObject.jsObjectGetScriptable.invoke(
args[i], ScriptRuntime.emptyArgs);
}
}
catch (InvocationTargetException e) {
// Just abandon conversion from JSObject
}
catch (IllegalAccessException e) {
// Just abandon conversion from JSObject
}
}
Member bestFit = null;
Class[] bestFitTypes = null;
java.util.Vector ambiguousMethods = null;
for (int i = 0; i < methodsOrCtors.length; i++) {
Member member = methodsOrCtors[i];
Class paramTypes[] = hasMethods
? ((Method) member).getParameterTypes()
: ((Constructor) member).getParameterTypes();
if (paramTypes.length != args.length) {
continue;
}
if (bestFitTypes == null) {
int j;
for (j = 0; j < paramTypes.length; j++) {
if (!NativeJavaObject.canConvert(args[j], paramTypes[j])) {
if (debug) printDebug("Rejecting ", member, args);
break;
}
}
if (j == paramTypes.length) {
if (debug) printDebug("Found ", member, args);
bestFit = member;
bestFitTypes = paramTypes;
}
}
else {
int preference =
NativeJavaMethod.preferSignature(args,
paramTypes,
bestFitTypes);
if (preference == PREFERENCE_AMBIGUOUS) {
if (debug) printDebug("Deferring ", member, args);
// add to "ambiguity list"
if (ambiguousMethods == null)
ambiguousMethods = new java.util.Vector();
ambiguousMethods.addElement(member);
}
else if (preference == PREFERENCE_FIRST_ARG) {
if (debug) printDebug("Substituting ", member, args);
bestFit = member;
bestFitTypes = paramTypes;
}
else {
if (debug) printDebug("Rejecting ", member, args);
}
}
}
if (ambiguousMethods == null)
return bestFit;
// Compare ambiguous methods with best fit, in case
// the current best fit removes the ambiguities.
for (int i = ambiguousMethods.size() - 1; i >= 0 ; i--) {
Member member = (Member)ambiguousMethods.elementAt(i);
Class paramTypes[] = hasMethods
? ((Method) member).getParameterTypes()
: ((Constructor) member).getParameterTypes();
int preference =
NativeJavaMethod.preferSignature(args,
paramTypes,
bestFitTypes);
if (preference == PREFERENCE_FIRST_ARG) {
if (debug) printDebug("Substituting ", member, args);
bestFit = member;
bestFitTypes = paramTypes;
ambiguousMethods.removeElementAt(i);
}
else if (preference == PREFERENCE_SECOND_ARG) {
if (debug) printDebug("Rejecting ", member, args);
ambiguousMethods.removeElementAt(i);
}
else {
if (debug) printDebug("UNRESOLVED: ", member, args);
}
}
if (ambiguousMethods.size() > 0) {
// PENDING: report remaining ambiguity
StringBuffer buf = new StringBuffer();
boolean isCtor = (bestFit instanceof Constructor);
ambiguousMethods.addElement(bestFit);
for (int i = 0; i < ambiguousMethods.size(); i++) {
if (i != 0) {
buf.append(", ");
}
Member member = (Member)ambiguousMethods.elementAt(i);
if (!isCtor) {
Class rtnType = ((Method)member).getReturnType();
buf.append(rtnType);
buf.append(' ');
}
buf.append(NativeJavaMethod.signature(member));
}
String errMsg;
if (isCtor) {
Object errArgs[] = {
bestFit.getName(),
NativeJavaMethod.scriptSignature(args),
buf.toString()
};
errMsg =
Context.getMessage("msg.constructor.ambiguous", errArgs);
}
else {
Object errArgs[] = {
bestFit.getDeclaringClass().getName(),
bestFit.getName(),
NativeJavaMethod.scriptSignature(args),
buf.toString()
};
errMsg = Context.getMessage("msg.method.ambiguous", errArgs);
}
throw
Context.reportRuntimeError(errMsg);
}
return bestFit;
}
/** Types are equal */
static final int PREFERENCE_EQUAL = 0;
static final int PREFERENCE_FIRST_ARG = 1;
static final int PREFERENCE_SECOND_ARG = 2;
/** No clear "easy" conversion */
static final int PREFERENCE_AMBIGUOUS = 3;
/**
* Determine which of two signatures is the closer fit.
* Returns one of PREFERENCE_EQUAL, PREFERENCE_FIRST_ARG,
* PREFERENCE_SECOND_ARG, or PREFERENCE_AMBIGUOUS.
*/
public static int preferSignature(Object[] args,
Class[] sig1, Class[] sig2) {
int preference = 0;
for (int j = 0; j < args.length; j++) {
Class type1 = sig1[j];
Class type2 = sig2[j];
if (type1 == type2) {
continue;
}
preference |=
NativeJavaMethod.preferConversion(args[j],
type1,
type2);
if (preference == PREFERENCE_AMBIGUOUS) {
break;
}
}
return preference;
}
/**
* Determine which of two types is the easier conversion.
* Returns one of PREFERENCE_EQUAL, PREFERENCE_FIRST_ARG,
* PREFERENCE_SECOND_ARG, or PREFERENCE_AMBIGUOUS.
*/
public static int preferConversion(Object fromObj,
Class toClass1, Class toClass2) {
int rank1 =
NativeJavaObject.getConversionWeight(fromObj, toClass1);
int rank2 =
NativeJavaObject.getConversionWeight(fromObj, toClass2);
if (rank1 == NativeJavaObject.CONVERSION_NONTRIVIAL &&
rank2 == NativeJavaObject.CONVERSION_NONTRIVIAL) {
if (toClass1.isAssignableFrom(toClass2)) {
return PREFERENCE_SECOND_ARG;
}
else if (toClass2.isAssignableFrom(toClass1)) {
return PREFERENCE_FIRST_ARG;
}
}
else {
if (rank1 < rank2) {
return PREFERENCE_FIRST_ARG;
}
else if (rank1 > rank2) {
return PREFERENCE_SECOND_ARG;
}
}
return PREFERENCE_AMBIGUOUS;
}
Method[] getMethods() {
return methods;
}
private static final boolean debug = false;
private static void printDebug(String msg, Member member, Object[] args) {
if (debug) {
System.err.println(" ----- " + msg +
member.getDeclaringClass().getName() +
"." + signature(member) +
" for arguments (" + scriptSignature(args) + ")");
}
}
Method methods[];
}

View File

@@ -0,0 +1,850 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
package org.mozilla.javascript;
import java.lang.reflect.*;
import java.util.Hashtable;
import java.util.Enumeration;
/**
* This class reflects non-Array Java objects into the JavaScript environment. It
* reflect fields directly, and uses NativeJavaMethod objects to reflect (possibly
* overloaded) methods.<p>
*
* @author Mike Shaver
* @see NativeJavaArray
* @see NativeJavaPackage
* @see NativeJavaClass
*/
public class NativeJavaObject implements Scriptable, Wrapper {
public NativeJavaObject(Scriptable scope, Object javaObject,
JavaMembers members)
{
this.parent = scope;
this.javaObject = javaObject;
this.members = members;
}
public NativeJavaObject(Scriptable scope, Object javaObject,
Class staticType)
{
this.parent = scope;
this.javaObject = javaObject;
Class dynamicType = javaObject != null ? javaObject.getClass()
: staticType;
members = JavaMembers.lookupClass(scope, dynamicType, staticType);
fieldAndMethods = members.getFieldAndMethodsObjects(javaObject, false);
}
public boolean has(String name, Scriptable start) {
return members.has(name, false);
}
public boolean has(int index, Scriptable start) {
return false;
}
public Object get(String name, Scriptable start) {
if (fieldAndMethods != null) {
Object result = fieldAndMethods.get(name);
if (result != null)
return result;
}
// TODO: passing 'this' as the scope is bogus since it has
// no parent scope
return members.get(this, name, javaObject, false);
}
public Object get(int index, Scriptable start) {
throw members.reportMemberNotFound(Integer.toString(index));
}
public void put(String name, Scriptable start, Object value) {
members.put(name, javaObject, value, false);
}
public void put(int index, Scriptable start, Object value) {
throw members.reportMemberNotFound(Integer.toString(index));
}
public boolean hasInstance(Scriptable value) {
// This is an instance of a Java class, so always return false
return false;
}
public void delete(String name) {
}
public void delete(int index) {
}
public Scriptable getPrototype() {
if (javaObject.getClass() == ScriptRuntime.StringClass) {
return ScriptableObject.getClassPrototype(parent, "String");
}
return null;
}
public void setPrototype(Scriptable prototype) {
}
/**
* Returns the parent (enclosing) scope of the object.
*/
public Scriptable getParentScope() {
return parent;
}
/**
* Sets the parent (enclosing) scope of the object.
*/
public void setParentScope(Scriptable m) {
parent = m;
}
public Object[] getIds() {
return members.getIds(false);
}
public static Object wrap(Scriptable scope, Object obj, Class staticType)
{
if (obj == null)
return obj;
Class cls = obj.getClass();
if (staticType != null && staticType.isPrimitive()) {
if (staticType == Void.TYPE)
return Undefined.instance;
if (staticType == Character.TYPE)
return new Integer((int) ((Character) obj).charValue());
return obj;
}
if (cls.isArray())
return NativeJavaArray.wrap(scope, obj);
if (obj instanceof Scriptable)
return obj;
if (Context.useJSObject && jsObjectClass != null &&
staticType != jsObjectClass && jsObjectClass.isInstance(obj))
{
try {
return jsObjectGetScriptable.invoke(obj, ScriptRuntime.emptyArgs);
}
catch (InvocationTargetException e) {
// Just abandon conversion from JSObject
}
catch (IllegalAccessException e) {
// Just abandon conversion from JSObject
}
}
return new NativeJavaObject(scope, obj, staticType);
}
public Object unwrap() {
return javaObject;
}
public String getClassName() {
return "JavaObject";
}
Function getConverter(String converterName) {
Object converterFunction = get(converterName, this);
if (converterFunction instanceof Function) {
return (Function) converterFunction;
}
return null;
}
Object callConverter(Function converterFunction)
throws JavaScriptException
{
Function f = (Function) converterFunction;
return f.call(Context.getContext(), f.getParentScope(),
this, new Object[0]);
}
Object callConverter(String converterName)
throws JavaScriptException
{
Function converter = getConverter(converterName);
if (converter == null) {
Object[] errArgs = { converterName, javaObject.getClass().getName() };
throw Context.reportRuntimeError(
Context.getMessage("msg.java.conversion.implicit_method",
errArgs));
}
return callConverter(converter);
}
public Object getDefaultValue(Class hint) {
if (hint == null || hint == ScriptRuntime.StringClass)
return javaObject.toString();
try {
if (hint == ScriptRuntime.BooleanClass)
return callConverter("booleanValue");
if (hint == ScriptRuntime.NumberClass) {
return callConverter("doubleValue");
}
// fall through to error message
} catch (JavaScriptException jse) {
// fall through to error message
}
throw Context.reportRuntimeError(
Context.getMessage("msg.default.value", null));
}
/**
* Determine whether we can/should convert between the given type and the
* desired one. This should be superceded by a conversion-cost calculation
* function, but for now I'll hide behind precedent.
*/
public static boolean canConvert(Object fromObj, Class to) {
int weight = NativeJavaObject.getConversionWeight(fromObj, to);
return (weight < CONVERSION_NONE);
}
static final int JSTYPE_UNDEFINED = 0; // undefined type
static final int JSTYPE_NULL = 1; // null
static final int JSTYPE_BOOLEAN = 2; // boolean
static final int JSTYPE_NUMBER = 3; // number
static final int JSTYPE_STRING = 4; // string
static final int JSTYPE_JAVA_CLASS = 5; // JavaClass
static final int JSTYPE_JAVA_OBJECT = 6; // JavaObject
static final int JSTYPE_JAVA_ARRAY = 7; // JavaArray
static final int JSTYPE_OBJECT = 8; // Scriptable
public static final byte CONVERSION_TRIVIAL = 1;
public static final byte CONVERSION_NONTRIVIAL = 0;
public static final byte CONVERSION_NONE = 99;
/**
* Derive a ranking based on how "natural" the conversion is.
* The special value CONVERSION_NONE means no conversion is possible,
* and CONVERSION_NONTRIVIAL signals that more type conformance testing
* is required.
* Based on
* <a href="http://www.mozilla.org/js/liveconnect/lc3_method_overloading.html">
* "preferred method conversions" from Live Connect 3</a>
*/
public static int getConversionWeight(Object fromObj, Class to) {
int fromCode = NativeJavaObject.getJSTypeCode(fromObj);
int result = CONVERSION_NONE;
switch (fromCode) {
case JSTYPE_UNDEFINED:
if (to == ScriptRuntime.StringClass ||
to == ScriptRuntime.ObjectClass) {
result = 1;
}
break;
case JSTYPE_NULL:
if (!to.isPrimitive()) {
result = 1;
}
break;
case JSTYPE_BOOLEAN:
// "boolean" is #1
if (to == Boolean.TYPE) {
result = 1;
}
else if (to == ScriptRuntime.BooleanClass) {
result = 2;
}
else if (to == ScriptRuntime.ObjectClass) {
result = 3;
}
else if (to == ScriptRuntime.StringClass) {
result = 4;
}
break;
case JSTYPE_NUMBER:
if (to.isPrimitive()) {
if (to == Double.TYPE) {
result = 1;
}
else if (to != Boolean.TYPE) {
result = 1 + NativeJavaObject.getSizeRank(to);
}
}
else {
if (to == ScriptRuntime.StringClass) {
// native numbers are #1-8
result = 9;
}
else if (to == ScriptRuntime.ObjectClass) {
result = 10;
}
else if (ScriptRuntime.NumberClass.isAssignableFrom(to)) {
// "double" is #1
result = 2;
}
}
break;
case JSTYPE_STRING:
if (to == ScriptRuntime.StringClass) {
result = 1;
}
else if (to == ScriptRuntime.ObjectClass) {
result = 2;
}
else if (to.isPrimitive() && to != Boolean.TYPE) {
if (to == Character.TYPE) {
result = 3;
}
else {
result = 4;
}
}
break;
case JSTYPE_JAVA_CLASS:
if (to == ScriptRuntime.ClassClass) {
result = 1;
}
else if (Context.useJSObject && jsObjectClass != null &&
jsObjectClass.isAssignableFrom(to)) {
result = 2;
}
else if (to == ScriptRuntime.ObjectClass) {
result = 3;
}
else if (to == ScriptRuntime.StringClass) {
result = 4;
}
break;
case JSTYPE_JAVA_OBJECT:
case JSTYPE_JAVA_ARRAY:
if (to == ScriptRuntime.StringClass) {
result = 2;
}
else if (to.isPrimitive() && to != Boolean.TYPE) {
result =
(fromCode == JSTYPE_JAVA_ARRAY) ?
CONVERSION_NONTRIVIAL :
2 + NativeJavaObject.getSizeRank(to);
}
else {
Object javaObj = fromObj;
if (javaObj instanceof NativeJavaObject) {
javaObj = ((NativeJavaObject)javaObj).unwrap();
}
if (to.isInstance(javaObj)) {
result = CONVERSION_NONTRIVIAL;
}
}
break;
case JSTYPE_OBJECT:
// Other objects takes #1-#3 spots
if (Context.useJSObject && jsObjectClass != null &&
jsObjectClass.isAssignableFrom(to)) {
result = 1;
}
else if (to == ScriptRuntime.ObjectClass) {
result = 2;
}
else if (to == ScriptRuntime.StringClass) {
result = 3;
}
else if (to.isPrimitive() || to != Boolean.TYPE) {
result = 3 + NativeJavaObject.getSizeRank(to);
}
break;
}
return result;
}
static int getSizeRank(Class aType) {
if (aType == Double.TYPE) {
return 1;
}
else if (aType == Float.TYPE) {
return 2;
}
else if (aType == Long.TYPE) {
return 3;
}
else if (aType == Integer.TYPE) {
return 4;
}
else if (aType == Short.TYPE) {
return 5;
}
else if (aType == Character.TYPE) {
return 6;
}
else if (aType == Byte.TYPE) {
return 7;
}
else if (aType == Boolean.TYPE) {
return CONVERSION_NONE;
}
else {
return 8;
}
}
static int getJSTypeCode(Object value) {
if (value == null) {
return JSTYPE_NULL;
}
else if (value == Undefined.instance) {
return JSTYPE_UNDEFINED;
}
else if (value instanceof Scriptable) {
if (value instanceof NativeJavaClass) {
return JSTYPE_JAVA_CLASS;
}
else if (value instanceof NativeJavaArray) {
return JSTYPE_JAVA_ARRAY;
}
else if (value instanceof NativeJavaObject) {
return JSTYPE_JAVA_OBJECT;
}
else {
return JSTYPE_OBJECT;
}
}
else {
Class valueClass = value.getClass();
if (valueClass == ScriptRuntime.StringClass) {
return JSTYPE_STRING;
}
else if (valueClass == ScriptRuntime.BooleanClass) {
return JSTYPE_BOOLEAN;
}
else if (value instanceof Number) {
return JSTYPE_NUMBER;
}
else if (valueClass == ScriptRuntime.ClassClass) {
return JSTYPE_JAVA_CLASS;
}
else if (valueClass.isArray()) {
return JSTYPE_JAVA_ARRAY;
}
else {
return JSTYPE_JAVA_OBJECT;
}
}
}
/**
* Type-munging for field setting and method invocation.
* Conforms to LC3 specification
*/
public static Object coerceType(Class type, Object value) {
if (value != null && value.getClass() == type) {
return value;
}
switch (NativeJavaObject.getJSTypeCode(value)) {
case JSTYPE_NULL:
// raise error if type.isPrimitive()
if (type.isPrimitive()) {
reportConversionError(value, type);
}
return null;
case JSTYPE_UNDEFINED:
if (type == ScriptRuntime.StringClass ||
type == ScriptRuntime.ObjectClass) {
return "undefined";
}
else {
reportConversionError("undefined", type);
}
break;
case JSTYPE_BOOLEAN:
// Under LC3, only JS Booleans can be coerced into a Boolean value
if (type == Boolean.TYPE ||
type == ScriptRuntime.BooleanClass ||
type == ScriptRuntime.ObjectClass) {
return value;
}
else if (type == ScriptRuntime.StringClass) {
return value.toString();
}
else {
reportConversionError(value, type);
}
break;
case JSTYPE_NUMBER:
if (type == ScriptRuntime.StringClass) {
return ScriptRuntime.toString(value);
}
else if (type == ScriptRuntime.ObjectClass) {
return coerceToNumber(Double.TYPE, value);
}
else if ((type.isPrimitive() && type != Boolean.TYPE) ||
ScriptRuntime.NumberClass.isAssignableFrom(type)) {
return coerceToNumber(type, value);
}
else {
reportConversionError(value, type);
}
break;
case JSTYPE_STRING:
if (type == ScriptRuntime.StringClass ||
type == ScriptRuntime.ObjectClass) {
return value;
}
else if (type == Character.TYPE ||
type == ScriptRuntime.CharacterClass) {
// Special case for converting a single char string to a
// character
// Placed here because it applies *only* to JS strings,
// not other JS objects converted to strings
if (((String)value).length() == 1) {
return new Character(((String)value).charAt(0));
}
else {
return coerceToNumber(type, value);
}
}
else if ((type.isPrimitive() && type != Boolean.TYPE) ||
ScriptRuntime.NumberClass.isAssignableFrom(type)) {
return coerceToNumber(type, value);
}
else {
reportConversionError(value, type);
}
break;
case JSTYPE_JAVA_CLASS:
if (Context.useJSObject && jsObjectClass != null &&
(type == ScriptRuntime.ObjectClass ||
jsObjectClass.isAssignableFrom(type))) {
return coerceToJSObject(type, (Scriptable)value);
}
else {
if (value instanceof Wrapper) {
value = ((Wrapper)value).unwrap();
}
if (type == ScriptRuntime.ClassClass ||
type == ScriptRuntime.ObjectClass) {
return value;
}
else if (type == ScriptRuntime.StringClass) {
return value.toString();
}
else {
reportConversionError(value, type);
}
}
break;
case JSTYPE_JAVA_OBJECT:
case JSTYPE_JAVA_ARRAY:
if (type.isPrimitive()) {
if (type == Boolean.TYPE) {
reportConversionError(value, type);
}
return coerceToNumber(type, value);
}
else {
if (value instanceof Wrapper) {
value = ((Wrapper)value).unwrap();
}
if (type == ScriptRuntime.StringClass) {
return value.toString();
}
else {
if (type.isInstance(value)) {
return value;
}
else {
reportConversionError(value, type);
}
}
}
break;
case JSTYPE_OBJECT:
if (Context.useJSObject && jsObjectClass != null &&
(type == ScriptRuntime.ObjectClass ||
jsObjectClass.isAssignableFrom(type))) {
return coerceToJSObject(type, (Scriptable)value);
}
else if (type == ScriptRuntime.StringClass) {
return ScriptRuntime.toString(value);
}
else if (type.isPrimitive()) {
if (type == Boolean.TYPE) {
reportConversionError(value, type);
}
return coerceToNumber(type, value);
}
else if (type.isInstance(value)) {
return value;
}
else {
reportConversionError(value, type);
}
break;
}
return value;
}
static Object coerceToJSObject(Class type, Scriptable value) {
// If JSObject compatibility is enabled, and the method wants it,
// wrap the Scriptable value in a JSObject.
if (ScriptRuntime.ScriptableClass.isAssignableFrom(type))
return value;
try {
Object ctorArgs[] = { value };
return jsObjectCtor.newInstance(ctorArgs);
} catch (InstantiationException instEx) {
throw new EvaluatorException("error generating JSObject wrapper for " +
value);
} catch (IllegalArgumentException argEx) {
throw new EvaluatorException("JSObject constructor doesn't want [Scriptable]!");
} catch (InvocationTargetException e) {
throw WrappedException.wrapException(e);
} catch (IllegalAccessException accessEx) {
throw new EvaluatorException("JSObject constructor is protected/private!");
}
}
static Object coerceToNumber(Class type, Object value) {
Class valueClass = value.getClass();
// Character
if (type == Character.TYPE || type == ScriptRuntime.CharacterClass) {
if (valueClass == ScriptRuntime.CharacterClass) {
return value;
}
return new Character((char)toInteger(value,
ScriptRuntime.CharacterClass,
Character.MIN_VALUE,
Character.MAX_VALUE));
}
// Double, Float
if (type == ScriptRuntime.ObjectClass ||
type == ScriptRuntime.DoubleClass || type == Double.TYPE) {
return valueClass == ScriptRuntime.DoubleClass
? value
: new Double(toDouble(value));
}
if (type == ScriptRuntime.FloatClass || type == Float.TYPE) {
if (valueClass == ScriptRuntime.FloatClass) {
return value;
}
else {
double number = toDouble(value);
if (Double.isInfinite(number) || Double.isNaN(number)
|| number == 0.0) {
return new Float((float)number);
}
else {
double absNumber = Math.abs(number);
if (absNumber < (double)Float.MIN_VALUE) {
return new Float((number > 0.0) ? +0.0 : -0.0);
}
else if (absNumber > (double)Float.MAX_VALUE) {
return new Float((number > 0.0) ?
Float.POSITIVE_INFINITY :
Float.NEGATIVE_INFINITY);
}
else {
return new Float((float)number);
}
}
}
}
// Integer, Long, Short, Byte
if (type == ScriptRuntime.IntegerClass || type == Integer.TYPE) {
if (valueClass == ScriptRuntime.IntegerClass) {
return value;
}
else {
return new Integer((int)toInteger(value,
ScriptRuntime.IntegerClass,
Integer.MIN_VALUE,
Integer.MAX_VALUE));
}
}
if (type == ScriptRuntime.LongClass || type == Long.TYPE) {
if (valueClass == ScriptRuntime.LongClass) {
return value;
}
else {
return new Long(toInteger(value,
ScriptRuntime.LongClass,
Long.MIN_VALUE,
Long.MAX_VALUE));
}
}
if (type == ScriptRuntime.ShortClass || type == Short.TYPE) {
if (valueClass == ScriptRuntime.ShortClass) {
return value;
}
else {
return new Short((short)toInteger(value,
ScriptRuntime.ShortClass,
Short.MIN_VALUE,
Short.MAX_VALUE));
}
}
if (type == ScriptRuntime.ByteClass || type == Byte.TYPE) {
if (valueClass == ScriptRuntime.ByteClass) {
return value;
}
else {
return new Byte((byte)toInteger(value,
ScriptRuntime.ByteClass,
Byte.MIN_VALUE,
Byte.MAX_VALUE));
}
}
return new Double(toDouble(value));
}
static double toDouble(Object value) {
if (value instanceof Number) {
return ((Number)value).doubleValue();
}
else if (value instanceof String) {
return ScriptRuntime.toNumber((String)value);
}
else if (value instanceof Scriptable) {
if (value instanceof Wrapper) {
// XXX: optimize tail-recursion?
return toDouble(((Wrapper)value).unwrap());
}
else {
return ScriptRuntime.toNumber(value);
}
}
else {
double result = Double.NaN;
Method meth;
try {
meth = value.getClass().getMethod("doubleValue", null);
}
catch (NoSuchMethodException e) {
meth = null;
}
catch (SecurityException e) {
meth = null;
}
if (meth != null) {
try {
return ((Number)meth.invoke(value, null)).doubleValue();
}
catch (IllegalAccessException e) {
// XXX: ignore, or error message?
reportConversionError(value, Double.TYPE);
}
catch (InvocationTargetException e) {
// XXX: ignore, or error message?
reportConversionError(value, Double.TYPE);
}
}
return ScriptRuntime.toNumber(value.toString());
}
}
static long toInteger(Object value, Class type, long min, long max) {
double d = toDouble(value);
if (Double.isInfinite(d) || Double.isNaN(d)) {
// Convert to string first, for more readable message
reportConversionError(ScriptRuntime.toString(value), type);
}
if (d > 0.0) {
d = Math.floor(d);
}
else {
d = Math.ceil(d);
}
if (d < (double)min || d > (double)max) {
// Convert to string first, for more readable message
reportConversionError(ScriptRuntime.toString(value), type);
}
return (long)d;
}
static void reportConversionError(Object value, Class type) {
Object[] args = {value, type};
throw Context.reportRuntimeError(Context.getMessage("msg.conversion.not.allowed", args));
}
public static void initJSObject() {
if (!Context.useJSObject)
return;
// if netscape.javascript.JSObject is in the CLASSPATH, enable JSObject
// compatability wrappers
jsObjectClass = null;
try {
jsObjectClass = Class.forName("netscape.javascript.JSObject");
Class ctorParms[] = { ScriptRuntime.ScriptableClass };
jsObjectCtor = jsObjectClass.getConstructor(ctorParms);
jsObjectGetScriptable = jsObjectClass.getMethod("getScriptable",
new Class[0]);
} catch (ClassNotFoundException classEx) {
// jsObjectClass already null
} catch (NoSuchMethodException methEx) {
// jsObjectClass already null
}
}
/**
* The parent scope of this object.
*/
protected Scriptable parent;
protected Object javaObject;
protected JavaMembers members;
private Hashtable fieldAndMethods;
static Class jsObjectClass;
static Constructor jsObjectCtor;
static Method jsObjectGetScriptable;
}

View File

@@ -0,0 +1,214 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
package org.mozilla.javascript;
import java.lang.reflect.*;
/**
* This class reflects Java packages into the JavaScript environment. We
* lazily reflect classes and subpackages, and use a caching/sharing
* system to ensure that members reflected into one JavaPackage appear
* in all other references to the same package (as with Packages.java.lang
* and java.lang).
*
* @author Mike Shaver
* @see NativeJavaArray
* @see NativeJavaObject
* @see NativeJavaClass
*/
public class NativeJavaPackage extends ScriptableObject {
// we know these are packages so we can skip the class check
// note that this is ok even if the package isn't present.
static final String[] commonPackages = {
"java.lang",
"java.lang.reflect",
"java.io",
"java.math",
"java.util",
"java.util.zip",
"java.text",
"java.text.resources",
"java.applet",
};
public static Scriptable init(Scriptable scope)
throws PropertyException
{
NativeJavaPackage packages = new NativeJavaPackage("");
packages.setPrototype(getObjectPrototype(scope));
packages.setParentScope(scope);
// We want to get a real alias, and not a distinct JavaPackage
// with the same packageName, so that we share classes and packages
// that are underneath.
NativeJavaPackage javaAlias = (NativeJavaPackage)packages.get("java",
packages);
// It's safe to downcast here since initStandardObjects takes
// a ScriptableObject.
ScriptableObject global = (ScriptableObject) scope;
global.defineProperty("Packages", packages, ScriptableObject.DONTENUM);
global.defineProperty("java", javaAlias, ScriptableObject.DONTENUM);
for (int i = 0; i < commonPackages.length; i++)
packages.forcePackage(commonPackages[i]);
NativeJavaObject.initJSObject();
String[] methods = { "getClass" };
global.defineFunctionProperties(methods, NativeJavaPackage.class,
ScriptableObject.DONTENUM);
// I think I'm supposed to return the prototype, but I don't have one.
return packages;
}
// set up a name which is known to be a package so we don't
// need to look for a class by that name
void forcePackage(String name) {
NativeJavaPackage pkg;
int end = name.indexOf('.');
if (end == -1)
end = name.length();
String id = name.substring(0, end);
Object cached = super.get(id, this);
if (cached != null && cached instanceof NativeJavaPackage) {
pkg = (NativeJavaPackage) cached;
} else {
String newPackage = packageName.length() == 0
? id
: packageName + "." + id;
pkg = new NativeJavaPackage(newPackage);
pkg.setParentScope(this);
pkg.setPrototype(this.prototype);
super.put(id, this, pkg);
}
if (end < name.length())
pkg.forcePackage(name.substring(end+1));
}
public NativeJavaPackage(String packageName) {
this.packageName = packageName;
}
public String getClassName() {
return "JavaPackage";
}
public boolean has(String id, int index, Scriptable start) {
return true;
}
public void put(String id, Scriptable start, Object value) {
// Can't add properties to Java packages. Sorry.
}
public void put(int index, Scriptable start, Object value) {
// Can't add properties to Java packages. Sorry.
}
public Object get(String id, Scriptable start) {
return getPkgProperty(id, start, true);
}
synchronized Object getPkgProperty(String name, Scriptable start,
boolean createPkg)
{
Object cached = super.get(name, start);
if (cached != NOT_FOUND)
return cached;
String newPackage = packageName.length() == 0
? name
: packageName + "." + name;
Context cx = Context.getContext();
SecuritySupport ss = cx.getSecuritySupport();
Scriptable newValue;
try {
if (ss != null && !ss.visibleToScripts(newPackage))
throw new ClassNotFoundException();
Class newClass = Class.forName(newPackage);
newValue = NativeJavaClass.wrap(getTopLevelScope(this), newClass);
newValue.setParentScope(this);
newValue.setPrototype(this.prototype);
} catch (ClassNotFoundException ex) {
if (createPkg) {
NativeJavaPackage pkg = new NativeJavaPackage(newPackage);
pkg.setParentScope(this);
pkg.setPrototype(this.prototype);
newValue = pkg;
} else {
newValue = null;
}
}
if (newValue != null) {
// Make it available for fast lookup and sharing of
// lazily-reflected constructors and static members.
super.put(name, start, newValue);
}
return newValue;
}
public Object get(int index, Scriptable start) {
return NOT_FOUND;
}
public Object getDefaultValue(Class ignored) {
return toString();
}
public String toString() {
return "[JavaPackage " + packageName + "]";
}
public static Scriptable getClass(Context cx, Scriptable thisObj,
Object[] args, Function funObj)
{
if (args.length > 0 && args[0] instanceof NativeJavaObject) {
NativeJavaObject nativeJavaObj = (NativeJavaObject) args[0];
Scriptable result = getTopLevelScope(thisObj);
Class cl = nativeJavaObj.unwrap().getClass();
// Evaluate the class name by getting successive properties of
// the string to find the appropriate NativeJavaClass object
String name = "Packages." + cl.getName();
int offset = 0;
for (;;) {
int index = name.indexOf('.', offset);
String propName = index == -1
? name.substring(offset)
: name.substring(offset, index);
Object prop = result.get(propName, result);
if (!(prop instanceof Scriptable))
break; // fall through to error
result = (Scriptable) prop;
if (index == -1)
return result;
offset = index+1;
}
}
throw Context.reportRuntimeError(
Context.getMessage("msg.not.java.obj", null));
}
private String packageName;
}

View File

@@ -0,0 +1,122 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
package org.mozilla.javascript;
/**
* This class implements the Math native object.
* See ECMA 15.8.
* @author Norris Boyd
*/
public class NativeMath extends ScriptableObject {
public static Scriptable init(Scriptable scope)
throws PropertyException
{
NativeMath m = new NativeMath();
m.setPrototype(getObjectPrototype(scope));
m.setParentScope(scope);
String[] names = { "acos", "asin", "atan", "atan2", "ceil",
"cos", "floor", "log", "random",
"sin", "sqrt", "tan" };
m.defineFunctionProperties(names, java.lang.Math.class,
ScriptableObject.DONTENUM);
// These functions exist in java.lang.Math, but
// are overloaded. Define our own wrappers.
String[] localNames = { "abs", "exp", "max", "min", "round", "pow" };
m.defineFunctionProperties(localNames, NativeMath.class,
ScriptableObject.DONTENUM);
final int attr = ScriptableObject.DONTENUM |
ScriptableObject.PERMANENT |
ScriptableObject.READONLY;
m.defineProperty("E", new Double(Math.E), attr);
m.defineProperty("PI", new Double(Math.PI), attr);
m.defineProperty("LN10", new Double(2.302585092994046), attr);
m.defineProperty("LN2", new Double(0.6931471805599453), attr);
m.defineProperty("LOG2E", new Double(1.4426950408889634), attr);
m.defineProperty("LOG10E", new Double(0.4342944819032518), attr);
m.defineProperty("SQRT1_2", new Double(0.7071067811865476), attr);
m.defineProperty("SQRT2", new Double(1.4142135623730951), attr);
// We know that scope is a Scriptable object since we
// constrained the type on initStandardObjects.
ScriptableObject global = (ScriptableObject) scope;
global.defineProperty("Math", m, ScriptableObject.DONTENUM);
return m;
}
public NativeMath() {
}
public String getClassName() {
return "Math";
}
public double abs(double d) {
if (d == 0.0)
return 0.0; // abs(-0.0) should be 0.0, but -0.0 < 0.0 == false
else if (d < 0.0)
return -d;
else
return d;
}
public double max(double x, double y) {
return Math.max(x, y);
}
public double min(double x, double y) {
return Math.min(x, y);
}
public double round(double d) {
if (d != d)
return d; // NaN
if (d == Double.POSITIVE_INFINITY || d == Double.NEGATIVE_INFINITY)
return d;
long l = Math.round(d);
if (l == 0) {
// We must propagate the sign of d into the result
if (d < 0.0)
return ScriptRuntime.negativeZero;
return d == 0.0 ? d : 0.0;
}
return (double) l;
}
public double pow(double x, double y) {
if (y == 0)
return 1.0; // Java's pow(NaN, 0) = NaN; we need 1
return Math.pow(x, y);
}
public double exp(double d) {
if (d == Double.POSITIVE_INFINITY)
return d;
if (d == Double.NEGATIVE_INFINITY)
return 0.0;
return Math.exp(d);
}
}

View File

@@ -0,0 +1,93 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
package org.mozilla.javascript;
/**
* This class implements the Number native object.
*
* See ECMA 15.7.
*
* @author Norris Boyd
*/
public class NativeNumber extends ScriptableObject {
public static void finishInit(Scriptable scope,
FunctionObject ctor, Scriptable proto)
{
final int attr = ScriptableObject.DONTENUM |
ScriptableObject.PERMANENT |
ScriptableObject.READONLY;
String[] names = { "NaN", "POSITIVE_INFINITY", "NEGATIVE_INFINITY",
"MAX_VALUE", "MIN_VALUE" };
double[] values = { ScriptRuntime.NaN, Double.POSITIVE_INFINITY,
Double.NEGATIVE_INFINITY, Double.MAX_VALUE,
Double.MIN_VALUE };
for (int i=0; i < names.length; i++) {
ctor.defineProperty(names[i], new Double(values[i]), attr);
}
}
/**
* Zero-parameter constructor: just used to create Number.prototype
*/
public NativeNumber() {
doubleValue = defaultValue;
}
public NativeNumber(double number) {
doubleValue = number;
}
public String getClassName() {
return "Number";
}
public static Object jsConstructor(Context cx, Object[] args,
Function funObj, boolean inNewExpr)
{
double d = args.length >= 1
? ScriptRuntime.toNumber(args[0])
: defaultValue;
if (inNewExpr) {
// new Number(val) creates a new Number object.
return new NativeNumber(d);
}
// Number(val) converts val to a number value.
return new Double(d);
}
public String toString() {
return jsFunction_toString(Undefined.instance);
}
public String jsFunction_toString(Object base) {
int i = base == Undefined.instance
? 10
: ScriptRuntime.toInt32(base);
return ScriptRuntime.numberToString(doubleValue, i);
}
public double jsFunction_valueOf() {
return doubleValue;
}
private static final double defaultValue = +0.0;
private double doubleValue;
}

View File

@@ -0,0 +1,128 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
package org.mozilla.javascript;
import java.util.Hashtable;
/**
* This class implements the Object native object.
* See ECMA 15.2.
* @author Norris Boyd
*/
public class NativeObject extends ScriptableObject {
public static void finishInit(Scriptable scope, FunctionObject ctor,
Scriptable proto)
{
Object obj = proto.get("valueOf", proto);
((FunctionObject) obj).setLength((short) 0);
}
public String getClassName() {
return "Object";
}
public static Object jsConstructor(Context cx, Object[] args,
Function ctorObj, boolean inNewExpr)
throws JavaScriptException
{
if (!inNewExpr) {
// FunctionObject.construct will set up parent, proto
return ctorObj.construct(cx, ctorObj.getParentScope(), args);
}
if (args.length == 0 || args[0] == null ||
args[0] == Undefined.instance)
{
return new NativeObject();
}
return ScriptRuntime.toObject(ctorObj.getParentScope(), args[0]);
}
public String toString() {
Context cx = Context.getContext();
if (cx != null)
return jsFunction_toString(cx, this, null, null);
else
return "[object " + getClassName() + "]";
}
public static String jsFunction_toString(Context cx, Scriptable thisObj,
Object[] args, Function funObj)
{
if (cx.getLanguageVersion() != cx.VERSION_1_2)
return "[object " + thisObj.getClassName() + "]";
return toSource(cx, thisObj, args, funObj);
}
public static String toSource(Context cx, Scriptable thisObj,
Object[] args, Function funObj)
{
Scriptable m = thisObj;
if (cx.iterating == null)
cx.iterating = new Hashtable(31);
if (cx.iterating.get(m) == Boolean.TRUE) {
return "{}"; // stop recursion
} else {
StringBuffer result = new StringBuffer("{");
Object[] ids = m.getIds();
for(int i=0; i < ids.length; i++) {
if (i > 0)
result.append(", ");
Object id = ids[i];
String idString = ScriptRuntime.toString(id);
Object p = (id instanceof String)
? m.get((String) id, m)
: m.get(((Number) id).intValue(), m);
if (p instanceof String) {
result.append(idString + ":\""
+ ScriptRuntime
.escapeString(ScriptRuntime.toString(p))
+ "\"");
} else {
/* wrap changes to cx.iterating in a try/finally
* so that the reference always gets removed, and
* we don't leak memory. Good place for weak
* references, if we had them.
*/
try {
cx.iterating.put(m, Boolean.TRUE); // stop recursion.
result.append(idString + ":" + ScriptRuntime.toString(p));
} finally {
cx.iterating.remove(m);
}
}
}
result.append("}");
return result.toString();
}
}
public static Object jsFunction_valueOf(Context cx, Scriptable thisObj,
Object[] args, Function funObj)
{
return thisObj;
}
}

View File

@@ -0,0 +1,153 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
package org.mozilla.javascript;
import java.io.StringReader;
import java.io.IOException;
/**
* The JavaScript Script object.
*
* Note that the C version of the engine uses XDR as the format used
* by freeze and thaw. Since this depends on the internal format of
* structures in the C runtime, we cannot duplicate it.
*
* Since we cannot replace 'this' as a result of the compile method,
* this class has a dual nature. Generated scripts will have a null
* 'script' field and will override 'exec' and 'call'. Scripts created
* using the JavaScript constructor will forward requests to the
* nonnull 'script' field.
*
* @since 1.3
* @author Norris Boyd
*/
public class NativeScript extends NativeFunction implements Script {
public NativeScript() {
}
/**
* Returns the name of this JavaScript class, "Script".
*/
public String getClassName() {
return "Script";
}
/**
* Initialize script.
*
* Does nothing here, but scripts will override with code
* to initialize contained functions, regexp literals, etc.
*/
public void initScript(Scriptable scope) {
}
/**
* The Java method defining the JavaScript Script constructor.
*
*/
public static Object jsConstructor(Context cx, Object[] args,
Function ctorObj, boolean inNewExpr)
{
String source = args.length == 0
? ""
: ScriptRuntime.toString(args[0]);
Scriptable scope = cx.ctorScope;
if (scope == null)
scope = ctorObj;
return compile(scope, source);
}
public static Script compile(Scriptable scope, String source) {
Context cx = Context.getContext();
StringReader reader = new StringReader(source);
try {
int[] linep = { 0 };
String filename = Context.getSourcePositionFromStack(linep);
if (filename == null) {
filename = "<Script object>";
linep[0] = 1;
}
Object securityDomain =
cx.getSecurityDomainForStackDepth(5);
return cx.compileReader(scope, reader, filename, linep[0],
securityDomain);
}
catch (IOException e) {
throw new RuntimeException("Unexpected IOException");
}
}
public Scriptable jsFunction_compile(String source) {
script = compile(null, source);
return this;
}
public Object jsFunction_exec() throws JavaScriptException {
Object[] msgArgs = { "exec" };
throw Context.reportRuntimeError(
Context.getMessage("msg.cant.call.indirect", msgArgs));
}
public static Object jsFunction_toString(Context cx, Scriptable thisObj,
Object[] args, Function funObj)
{
Script thisScript = ((NativeScript) thisObj).script;
if (thisScript == null)
thisScript = (Script) thisObj;
Scriptable scope = getTopLevelScope(thisObj);
return cx.decompileScript(thisScript, scope, 0);
}
/*
* Override method in NativeFunction to avoid ever returning "anonymous"
*/
public String jsGet_name() {
return "";
}
/**
* Execute the script.
*
* Will be overridden by generated scripts; needed to implement Script.
*/
public Object exec(Context cx, Scriptable scope)
throws JavaScriptException
{
return script == null ? Undefined.instance : script.exec(cx, scope);
}
public Object call(Context cx, Scriptable scope, Scriptable thisObj,
Object[] args)
throws JavaScriptException
{
return exec(cx, scope);
}
public Scriptable construct(Context cx, Scriptable scope, Object[] args)
throws JavaScriptException
{
String message = Context.getMessage("msg.script.is.not.constructor", null);
throw Context.reportRuntimeError(message);
}
private Script script;
}

View File

@@ -0,0 +1,708 @@
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
package org.mozilla.javascript;
import java.lang.reflect.Method;
import java.util.Vector;
/**
* This class implements the String native object.
*
* See ECMA 15.5.
*
* String methods for dealing with regular expressions are
* ported directly from C. Latest port is from version 1.40.12.19
* in the JSFUN13_BRANCH.
*
* @author Mike McCabe
* @author Norris Boyd
*/
public class NativeString extends ScriptableObject implements Wrapper {
/**
* Zero-parameter constructor: just used to create String.prototype
*/
public NativeString() {
string = defaultValue;
}
public static void finishInit(Scriptable scope, FunctionObject ctor,
Scriptable proto)
{
// Most of the methods of String.prototype are "vararg" form
// so that they can convert the "this" value to string, rather
// than being restricted to just operating on NativeString
// objects. However, this means that the values of the "length"
// properties of these methods are set to 1 by the constructor
// for FunctionObject. We must therefore fetch the function
// objects and set the length to the appropriate value.
String[] specialLengthNames = { "indexOf",
"lastIndexOf",
"substring",
"toUpperCase",
"toLowerCase",
"toString",
};
short[] specialLengthValues = { 2,
2,
2,
0,
0,
0,
};
for (int i=0; i < specialLengthNames.length; i++) {
Object obj = proto.get(specialLengthNames[i], proto);
((FunctionObject) obj).setLength(specialLengthValues[i]);
}
}
public NativeString(String s) {
string = s;
}
public String getClassName() {
return "String";
}
public static String jsStaticFunction_fromCharCode(Context cx,
Scriptable thisObj,
Object[] args,
Function funObj)
{
if (args.length < 1)
return "";
StringBuffer s = new java.lang.StringBuffer();
for (int i=0; i < args.length; i++) {
s.append(ScriptRuntime.toUint16(args[i]));
}
return s.toString();
}
public static Object jsConstructor(Context cx, Object[] args,
Function ctorObj, boolean inNewExpr)
{
String s = args.length >= 1
? ScriptRuntime.toString(args[0])
: defaultValue;
if (inNewExpr) {
// new String(val) creates a new String object.
return new NativeString(s);
}
// String(val) converts val to a string value.
return s;
}
public String toString() {
return string;
}
/* ECMA 15.5.4.2: 'the toString function is not generic.' */
public String jsFunction_toString() {
return string;
}
public String jsFunction_valueOf() {
return string;
}
/* Make array-style property lookup work for strings.
* XXX is this ECMA? A version check is probably needed. In js too.
*/
public Object get(int index, Scriptable start) {
if (index >= 0 && index < string.length())
return string.substring(index, index + 1);
return super.get(index, start);
}
public void put(int index, Scriptable start, Object value) {
if (index >= 0 && index < string.length())
return;
super.put(index, start, value);
}
/**
*
* See ECMA 15.5.4.[4,5]
*/
public static String jsFunction_charAt(Context cx, Scriptable thisObj,
Object[] args, Function funObj)
{
if (args.length < 1)
args = ScriptRuntime.padArguments(args, 1);
// this'll return 0 if undefined... seems
// to be ECMA.
String target = ScriptRuntime.toString(thisObj);
double pos = ScriptRuntime.toInteger(args[0]);
if (pos < 0 || pos >= target.length())
return "";
return target.substring((int)pos, (int)pos + 1);
}
public static double jsFunction_charCodeAt(Context cx, Scriptable thisObj,
Object[] args, Function funObj)
{
if (args.length < 1)
args = ScriptRuntime.padArguments(args, 1);
String target = ScriptRuntime.toString(thisObj);
double pos = ScriptRuntime.toInteger(args[0]);
if (pos < 0 || pos >= target.length()) {
return ScriptRuntime.NaN;
}
return target.charAt((int)pos);
}
/**
*
* See ECMA 15.5.4.6. Uses Java String.indexOf()
* OPT to add - BMH searching from jsstr.c.
*/
public static int jsFunction_indexOf(Context cx, Scriptable thisObj,
Object[] args, Function funObj)
{
if (args.length < 2)
args = ScriptRuntime.padArguments(args, 2);
String target = ScriptRuntime.toString(thisObj);
String search = ScriptRuntime.toString(args[0]);
double begin = ScriptRuntime.toInteger(args[1]);
if (begin > target.length()) {
return -1;
} else {
if (begin < 0)
begin = 0;
return target.indexOf(search, (int)begin);
}
}
/**
*
* See ECMA 15.5.4.7
*
*/
public static int jsFunction_lastIndexOf(Context cx, Scriptable thisObj,
Object[] args, Function funObj)
{
if (args.length < 2)
args = ScriptRuntime.padArguments(args, 2);
String target = ScriptRuntime.toString(thisObj);
String search = ScriptRuntime.toString(args[0]);
double end = ScriptRuntime.toNumber(args[1]);
if (end != end || end > target.length())
end = target.length();
else if (end < 0)
end = 0;
return target.lastIndexOf(search, (int)end);
}
/*
* Used by js_split to find the next split point in target,
* starting at offset ip and looking either for the given
* separator substring, or for the next re match. ip and
* matchlen must be reference variables (assumed to be arrays of
* length 1) so they can be updated in the leading whitespace or
* re case.
*
* Return -1 on end of string, >= 0 for a valid index of the next
* separator occurrence if found, or the string length if no
* separator is found.
*/
private static int find_split(Function funObj, String target,
String separator, Object re,
int[] ip, int[] matchlen, boolean[] matched,
String[][] parensp)
{
int i = ip[0];
int length = target.length();
Context cx = Context.getContext();
int version = cx.getLanguageVersion();
/*
* Perl4 special case for str.split(' '), only if the user has selected
* JavaScript1.2 explicitly. Split on whitespace, and skip leading w/s.
* Strange but true, apparently modeled after awk.
*/
if (version == Context.VERSION_1_2 &&
re == null && separator.length() == 1 && separator.charAt(0) == ' ')
{
/* Skip leading whitespace if at front of str. */
if (i == 0) {
while (i < length && Character.isWhitespace(target.charAt(i)))
i++;
ip[0] = i;
}
/* Don't delimit whitespace at end of string. */
if (i == length)
return -1;
/* Skip over the non-whitespace chars. */
while (i < length
&& !Character.isWhitespace(target.charAt(i)))
i++;
/* Now skip the next run of whitespace. */
int j = i;
while (j < length && Character.isWhitespace(target.charAt(j)))
j++;
/* Update matchlen to count delimiter chars. */
matchlen[0] = j - i;
return i;
}
/*
* Stop if past end of string. If at end of string, we will
* return target length, so that
*
* "ab,".split(',') => new Array("ab", "")
*
* and the resulting array converts back to the string "ab,"
* for symmetry. NB: This differs from perl, which drops the
* trailing empty substring if the LIMIT argument is omitted.
*/
if (i > length)
return -1;
/*
* Match a regular expression against the separator at or
* above index i. Return -1 at end of string instead of
* trying for a match, so we don't get stuck in a loop.
*/
if (re != null) {
return cx.getRegExpProxy().find_split(funObj, target,
separator, re,
ip, matchlen, matched,
parensp);
}
/*
* Deviate from ECMA by never splitting an empty string by any separator
* string into a non-empty array (an array of length 1 that contains the
* empty string).
*/
if (version != Context.VERSION_DEFAULT && version < Context.VERSION_1_3
&& length == 0)
return -1;
/*
* Special case: if sep is the empty string, split str into
* one character substrings. Let our caller worry about
* whether to split once at end of string into an empty
* substring.
*
* For 1.2 compatibility, at the end of the string, we return the length as
* the result, and set the separator length to 1 -- this allows the caller
* to include an additional null string at the end of the substring list.
*/
if (separator.length() == 0) {
if (version == Context.VERSION_1_2) {
if (i == length) {
matchlen[0] = 1;
return i;
}
return i + 1;
}
return (i == length) ? -1 : i + 1;
}
/* Punt to j.l.s.indexOf; return target length if seperator is
* not found.
*/
if (ip[0] >= length)
return length;
i = target.indexOf(separator, ip[0]);
return (i != -1) ? i : length;
}
/**
* See ECMA 15.5.4.8. Modified to match JS 1.2 - optionally takes
* a limit argument and accepts a regular expression as the split
* argument.
*/
public static Object jsFunction_split(Context cx, Scriptable thisObj,
Object[] args, Function funObj)
{
String target = ScriptRuntime.toString(thisObj);
// create an empty Array to return;
Scriptable scope = getTopLevelScope(funObj);
Scriptable result = ScriptRuntime.newObject(cx, scope, "Array", null);
// return an array consisting of the target if no separator given
// don't check against undefined, because we want
// 'fooundefinedbar'.split(void 0) to split to ['foo', 'bar']
if (args.length < 1) {
result.put(0, result, target);
return result;
}
// Use the second argument as the split limit, if given.
boolean limited = (args.length > 1) && (args[1] != Undefined.instance);
long limit = 0; // Initialize to avoid warning.
if (limited) {
/* Clamp limit between 0 and 1 + string length. */
limit = ScriptRuntime.toUint32(args[1]);
if (limit > target.length())
limit = 1 + target.length();
}
String separator = null;
int[] matchlen = { 0 };
Object re = null;
RegExpProxy reProxy = cx.getRegExpProxy();
if (reProxy != null && reProxy.isRegExp(args[0])) {
re = args[0];
} else {
separator = ScriptRuntime.toString(args[0]);
matchlen[0] = separator.length();
}
// split target with separator or re
int[] ip = { 0 };
int match;
int len = 0;
boolean[] matched = { false };
String[][] parens = { null };
while ((match = find_split(funObj, target, separator, re, ip,
matchlen, matched, parens)) >= 0)
{
if ((limited && len >= limit) || (match > target.length()))
break;
String substr;
if (target.length() == 0)
substr = target;
else
substr = target.substring(ip[0], match);
result.put(len, result, substr);
len++;
/*
* Imitate perl's feature of including parenthesized substrings
* that matched part of the delimiter in the new array, after the
* split substring that was delimited.
*/
if (re != null && matched[0] == true) {
int size = parens[0].length;
for (int num = 0; num < size; num++) {
if (limited && len >= limit)
break;
result.put(len, result, parens[0][num]);
len++;
}
matched[0] = false;
}
ip[0] = match + matchlen[0];
if (cx.getLanguageVersion() < Context.VERSION_1_3
&& cx.getLanguageVersion() != Context.VERSION_DEFAULT)
{
/*
* Deviate from ECMA to imitate Perl, which omits a final
* split unless a limit argument is given and big enough.
*/
if (!limited && ip[0] == target.length())
break;
}
}
return result;
}
/**
*
* See ECMA 15.5.4.[9,10]
*/
public static String jsFunction_substring(Context cx, Scriptable thisObj,
Object[] args, Function funObj)
{
if (args.length < 1)
args = ScriptRuntime.padArguments(args, 1);
String target = ScriptRuntime.toString(thisObj);
int length = target.length();
double start = ScriptRuntime.toInteger(args[0]);
double end;
if (start < 0)
start = 0;
else if (start > length)
start = length;
if (args.length == 1) {
end = length;
} else {
end = ScriptRuntime.toInteger(args[1]);
if (end < 0)
end = 0;
else if (end > length)
end = length;
// swap if end < start
if (end < start) {
if (cx.getLanguageVersion() != Context.VERSION_1_2) {
double temp = start;
start = end;
end = temp;
} else {
// Emulate old JDK1.0 java.lang.String.substring()
end = start;
}
}
}
return target.substring((int)start, (int)end);
}
/**
*
* See ECMA 15.5.4.[11,12]
*/
public static String jsFunction_toLowerCase(Context cx, Scriptable thisObj,
Object[] args, Function funObj)
{
String target = ScriptRuntime.toString(thisObj);
return target.toLowerCase();
}
public static String jsFunction_toUpperCase(Context cx, Scriptable thisObj,
Object[] args, Function funObj)
{
String target = ScriptRuntime.toString(thisObj);
return target.toUpperCase();
}
public double jsGet_length() {
return (double) string.length();
}
/**
* Non-ECMA methods.
*/
public static String jsFunction_substr(Context cx, Scriptable thisObj,
Object[] args, Function funObj)
{
String target = ScriptRuntime.toString(thisObj);
if (args.length < 1)
return target;
double begin = ScriptRuntime.toInteger(args[0]);
double end;
int length = target.length();
if (begin < 0) {
begin += length;
if (begin < 0)
begin = 0;
} else if (begin > length) {
begin = length;
}
if (args.length == 1) {
end = length;
} else {
end = ScriptRuntime.toInteger(args[1]);
if (end < 0)
end = 0;
end += begin;
if (end > length)
end = length;
}
return target.substring((int)begin, (int)end);
}
/**
* Python-esque sequence operations.
*/
public static String jsFunction_concat(Context cx, Scriptable thisObj,
Object[] args, Function funObj)
{
StringBuffer result = new StringBuffer();
result.append(ScriptRuntime.toString(thisObj));
for (int i = 0; i < args.length; i++)
result.append(ScriptRuntime.toString(args[i]));
return result.toString();
}
public static String jsFunction_slice(Context cx, Scriptable thisObj,
Object[] args, Function funObj)
{
String target = ScriptRuntime.toString(thisObj);
if (args.length != 0) {
double begin = ScriptRuntime.toInteger(args[0]);
double end;
int length = target.length();
if (begin < 0) {
begin += length;
if (begin < 0)
begin = 0;
} else if (begin > length) {
begin = length;
}
if (args.length == 1) {
end = length;
} else {
end = ScriptRuntime.toInteger(args[1]);
if (end < 0) {
end += length;
if (end < 0)
end = 0;
} else if (end > length) {
end = length;
}
if (end < begin)
end = begin;
}
return target.substring((int)begin, (int)end);
}
return target;
}
/**
* HTML composition aids.
*/
private String tagify(String begin, String end, String value) {
StringBuffer result = new StringBuffer();
result.append('<');
result.append(begin);
if (value != null) {
result.append('=');
result.append(value);
}
result.append('>');
result.append(this.string);
result.append("</");
result.append((end == null) ? begin : end);
result.append('>');
return result.toString();
}
public String jsFunction_bold() {
return tagify("B", null, null);
}
public String jsFunction_italics() {
return tagify("I", null, null);
}
public String jsFunction_fixed() {
return tagify("TT", null, null);
}
public String jsFunction_strike() {
return tagify("STRIKE", null, null);
}
public String jsFunction_small() {
return tagify("SMALL", null, null);
}
public String jsFunction_big() {
return tagify("BIG", null, null);
}
public String jsFunction_blink() {
return tagify("BLINK", null, null);
}
public String jsFunction_sup() {
return tagify("SUP", null, null);
}
public String jsFunction_sub() {
return tagify("SUB", null, null);
}
public String jsFunction_fontsize(String value) {
return tagify("FONT SIZE", "FONT", value);
}
public String jsFunction_fontcolor(String value) {
return tagify("FONT COLOR", "FONT", value);
}
public String jsFunction_link(String value) {
return tagify("A HREF", "A", value);
}
public String jsFunction_anchor(String value) {
return tagify("A NAME", "A", value);
}
/**
* Unwrap this NativeString as a j.l.String for LiveConnect use.
*/
public Object unwrap() {
return string;
}
public static Object jsFunction_match(Context cx, Scriptable thisObj,
Object[] args, Function funObj)
throws JavaScriptException
{
return checkReProxy(cx).match(cx, thisObj, args, funObj);
}
public static Object jsFunction_search(Context cx, Scriptable thisObj,
Object[] args, Function funObj)
throws JavaScriptException
{
return checkReProxy(cx).search(cx, thisObj, args, funObj);
}
public static Object jsFunction_replace(Context cx, Scriptable thisObj,
Object[] args, Function funObj)
throws JavaScriptException
{
return checkReProxy(cx).replace(cx, thisObj, args, funObj);
}
private static RegExpProxy checkReProxy(Context cx) {
RegExpProxy result = cx.getRegExpProxy();
if (result == null) {
throw cx.reportRuntimeError(cx.getMessage("msg.no.regexp", null));
}
return result;
}
private static final String defaultValue = "";
private String string;
}

Some files were not shown because too many files have changed in this diff Show More