Initial import of OAK java build management

master
nathan 2014-12-25 19:53:27 +01:00
commit 33ffb03aab
48 changed files with 9276 additions and 0 deletions

15
.classpath Normal file
View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="lib" path="libs/bcpkix-jdk15on-151.jar" sourcepath="libs/bcpkix-jdk15on-151-src.zip"/>
<classpathentry kind="lib" path="libs/slf4j-api-1.7.5.jar" sourcepath="libs/slf4j-api-1.7.5-sources.zip"/>
<classpathentry kind="lib" path="libs/wildcard-1.03.jar" sourcepath="libs/wildcard-1.03-src.zip"/>
<classpathentry kind="lib" path="libs/fast-md5/fast-md5.jar" sourcepath="libs/fast-md5/fast-md5-source.zip"/>
<classpathentry kind="lib" path="libs/javatar-2.5.jar" sourcepath="libs/javatar-2.5-src.zip"/>
<classpathentry combineaccessrules="false" kind="src" path="/Dorkbox-Util"/>
<classpathentry combineaccessrules="false" kind="src" path="/JavaLauncher-Util"/>
<classpathentry kind="lib" path="libs/bcprov-jdk15on-151.jar"/>
<classpathentry kind="lib" path="libs/yamlbeans-1.08.jar"/>
<classpathentry kind="output" path="classes"/>
</classpath>

5
.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
/classes/
/staging/
*.ini
*.key
temp.lzma

17
.project Normal file
View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>OAK</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

90
LICENSE Normal file
View File

@ -0,0 +1,90 @@
- Dorkbox OAK - Apache 2.0 License
https://github.com/dorkbox
Copyright 2012, dorkbox, llc
Java project management and build tool, using the Java language
- AnnotationDetector - Apache 2.0 License
https://github.com/rmuller/infomas-asl
Copyright 2011 - 2014, XIAM Solutions B.V. (http://www.xiam.nl)
- BouncyCastle - MIT License
http://www.bouncycastle.org
Copyright 2000-2009, The Legion Of The Bouncy Castle
- Dorkbox Utils - Apache 2.0 License
https://github.com/dorkbox
Copyright 2010, dorkbox, llc
- FastMD5 - LGPL v3 License
http://www.twmacinta.com/myjava/fast_md5.php
Copyright 1996, Santeri Paavolainen, Helsinki Finland
Many changes Copyright 2002 - 2010 Timothy W Macinta
Originally written by Santeri Paavolainen, Helsinki Finland 1996
- FilenameUtils.java (normalize + dependencies) - Apache 2.0 License
http://commons.apache.org/proper/commons-io/
Copyright 2013, ASF
Kevin A. Burton
Scott Sanders
Daniel Rall
Christoph.Reck
Peter Donald
Jeff Turner
Matthew Hawthorne
Martin Cooper
Jeremias Maerki
Stephen Colebourne
- Javatar - Public Domain
http://www.trustice.com/java/tar
Timothy Gerard Endres, time@gjt.org
- LZMA-Java - Apache 2.0 License
http://jponge.github.com/lzma-java
http://www.7-zip.org/sdk.html
Copyright 2014 Igor Pavlov
Julien Ponge (julien.ponge@gmail.com)
- MiG Base64 - BSD License
http://migbase64.sourceforge.net/
Copyright 2004, Mikael Grev, MiG InfoCom AB. (base64@miginfocom.com)
High performance base64 encoder & decoder
- OpenJDK - GPL v2 License, with Classpath exception
http://openjdk.java.net
https://github.com/alexkasko/openjdk-unofficial-builds
Copyright 2007, Sun Microsystems, Inc
http://www.gnu.org/software/classpath/license.html
When GNU Classpath is used unmodified as the core class library for a virtual machine,
compiler for the java language, or for a program written in the java programming language
it does not affect the licensing for distributing those programs directly.
- Scar - BSD License
https://github.com/EsotericSoftware/scar
Copyright 2011, Nathan Sweet
- SLF4J - MIT License
http://www.slf4j.org/
Copyright 2004-2008, QOS.ch
- Wildcard - BSD License
https://github.com/EsotericSoftware/wildcard
Copyright 2008, Nathan Sweet
- YamlBeans - BSD License
https://github.com/EsotericSoftware/yamlbeans
Copyright 2006, Ola Bini
Copyright 2008, Nathan Sweet

218
LICENSE.Apachev2 Normal file
View File

@ -0,0 +1,218 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

26
LICENSE.BSD Normal file
View File

@ -0,0 +1,26 @@
BSD License
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the <ORGANIZATION> 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 TINKERPOP 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.

347
LICENSE.GPLv2_CP Normal file
View File

@ -0,0 +1,347 @@
The GNU General Public License (GPL)
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies of this license
document, but changing it is not allowed.
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 Library 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.
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., 59
Temple Place, Suite 330, Boston, MA 02111-1307 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 Library General Public
License instead of this License.
"CLASSPATH" EXCEPTION TO THE GPL
Certain source files distributed by Oracle America and/or its affiliates are
subject to the following clarification and special exception to the GPL, but
only where Oracle has expressly included in the particular source file's header
the words "Oracle designates this particular file as subject to the "Classpath"
exception as provided by Oracle in the LICENSE file that accompanied this code."
Linking this library statically or dynamically with other modules is making
a combined work based on this library. Thus, the terms and conditions of
the GNU General Public License cover the whole combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent modules,
and to copy and distribute the resulting executable under terms of your
choice, provided that you also meet, for each linked independent module,
the terms and conditions of the license of that module. An independent
module is a module which is not derived from or based on this library. If
you modify this library, you may extend this exception to your version of
the library, but you are not obligated to do so. If you do not wish to do
so, delete this exception statement from your version.

165
LICENSE.LGPLv3 Normal file
View File

@ -0,0 +1,165 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

21
LICENSE.MIT Normal file
View File

@ -0,0 +1,21 @@
MIT License
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

121
LICENSE.Public Normal file
View File

@ -0,0 +1,121 @@
Creative Commons Legal Code
CC0 1.0 Universal
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
HEREUNDER.
Statement of Purpose
The laws of most jurisdictions throughout the world automatically confer
exclusive Copyright and Related Rights (defined below) upon the creator
and subsequent owner(s) (each and all, an "owner") of an original work of
authorship and/or a database (each, a "Work").
Certain owners wish to permanently relinquish those rights to a Work for
the purpose of contributing to a commons of creative, cultural and
scientific works ("Commons") that the public can reliably and without fear
of later claims of infringement build upon, modify, incorporate in other
works, reuse and redistribute as freely as possible in any form whatsoever
and for any purposes, including without limitation commercial purposes.
These owners may contribute to the Commons to promote the ideal of a free
culture and the further production of creative, cultural and scientific
works, or to gain reputation or greater distribution for their Work in
part through the use and efforts of others.
For these and/or other purposes and motivations, and without any
expectation of additional consideration or compensation, the person
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
is an owner of Copyright and Related Rights in the Work, voluntarily
elects to apply CC0 to the Work and publicly distribute the Work under its
terms, with knowledge of his or her Copyright and Related Rights in the
Work and the meaning and intended legal effect of CC0 on those rights.
1. Copyright and Related Rights. A Work made available under CC0 may be
protected by copyright and related or neighboring rights ("Copyright and
Related Rights"). Copyright and Related Rights include, but are not
limited to, the following:
i. the right to reproduce, adapt, distribute, perform, display,
communicate, and translate a Work;
ii. moral rights retained by the original author(s) and/or performer(s);
iii. publicity and privacy rights pertaining to a person's image or
likeness depicted in a Work;
iv. rights protecting against unfair competition in regards to a Work,
subject to the limitations in paragraph 4(a), below;
v. rights protecting the extraction, dissemination, use and reuse of data
in a Work;
vi. database rights (such as those arising under Directive 96/9/EC of the
European Parliament and of the Council of 11 March 1996 on the legal
protection of databases, and under any national implementation
thereof, including any amended or successor version of such
directive); and
vii. other similar, equivalent or corresponding rights throughout the
world based on applicable law or treaty, and any national
implementations thereof.
2. Waiver. To the greatest extent permitted by, but not in contravention
of, applicable law, Affirmer hereby overtly, fully, permanently,
irrevocably and unconditionally waives, abandons, and surrenders all of
Affirmer's Copyright and Related Rights and associated claims and causes
of action, whether now known or unknown (including existing as well as
future claims and causes of action), in the Work (i) in all territories
worldwide, (ii) for the maximum duration provided by applicable law or
treaty (including future time extensions), (iii) in any current or future
medium and for any number of copies, and (iv) for any purpose whatsoever,
including without limitation commercial, advertising or promotional
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
member of the public at large and to the detriment of Affirmer's heirs and
successors, fully intending that such Waiver shall not be subject to
revocation, rescission, cancellation, termination, or any other legal or
equitable action to disrupt the quiet enjoyment of the Work by the public
as contemplated by Affirmer's express Statement of Purpose.
3. Public License Fallback. Should any part of the Waiver for any reason
be judged legally invalid or ineffective under applicable law, then the
Waiver shall be preserved to the maximum extent permitted taking into
account Affirmer's express Statement of Purpose. In addition, to the
extent the Waiver is so judged Affirmer hereby grants to each affected
person a royalty-free, non transferable, non sublicensable, non exclusive,
irrevocable and unconditional license to exercise Affirmer's Copyright and
Related Rights in the Work (i) in all territories worldwide, (ii) for the
maximum duration provided by applicable law or treaty (including future
time extensions), (iii) in any current or future medium and for any number
of copies, and (iv) for any purpose whatsoever, including without
limitation commercial, advertising or promotional purposes (the
"License"). The License shall be deemed effective as of the date CC0 was
applied by Affirmer to the Work. Should any part of the License for any
reason be judged legally invalid or ineffective under applicable law, such
partial invalidity or ineffectiveness shall not invalidate the remainder
of the License, and in such case Affirmer hereby affirms that he or she
will not (i) exercise any of his or her remaining Copyright and Related
Rights in the Work or (ii) assert any associated claims and causes of
action with respect to the Work, in either case contrary to Affirmer's
express Statement of Purpose.
4. Limitations and Disclaimers.
a. No trademark or patent rights held by Affirmer are waived, abandoned,
surrendered, licensed or otherwise affected by this document.
b. Affirmer offers the Work as-is and makes no representations or
warranties of any kind concerning the Work, express, implied,
statutory or otherwise, including without limitation warranties of
title, merchantability, fitness for a particular purpose, non
infringement, or the absence of latent or other defects, accuracy, or
the present or absence of errors, whether or not discoverable, all to
the greatest extent permissible under applicable law.
c. Affirmer disclaims responsibility for clearing rights of other persons
that may apply to the Work or any use thereof, including without
limitation any person's Copyright and Related Rights in the Work.
Further, Affirmer disclaims responsibility for obtaining any necessary
consents, permissions or other rights required for any use of the
Work.
d. Affirmer understands and acknowledges that Creative Commons is not a
party to this document and has no duty or obligation with respect to
this CC0 or use of the Work.

22
README.md Normal file
View File

@ -0,0 +1,22 @@
OAK
===
Dorkbox OAK is a Java project management and build tool, using the Java language.
The main distinction between this tool and others, such as Ant, Maven, Ivy, Gradle, etc. is that
*this* build tool lets you work directly in Java. Since you are building a Java project, it can
safely be assumed that you already know Java, why use XML, Groovy, or some other language to build
your project?
- This is for cross-platform use, specifically - linux 32/64, mac 32/64, and windows 32/64. Java 6+
For example:
- See Build.java to see an example
OR, for a "real world" example
- See the example code in the wiki, which is what is used to build OAK
- Then, java -jar libs/OAK.jar build oak

432
src/dorkbox/Build.java Normal file
View File

@ -0,0 +1,432 @@
/*
* Copyright 2012 dorkbox, llc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dorkbox;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import com.esotericsoftware.wildcard.Paths;
import dorkbox.build.ProjectBasics;
import dorkbox.build.ProjectJava;
import dorkbox.build.SimpleArgs;
import dorkbox.build.util.BuildLog;
import dorkbox.build.util.BuildParser;
import dorkbox.build.util.ByteClassloader;
import dorkbox.build.util.ClassByteIterator;
import dorkbox.build.util.jar.Pack200Util;
import dorkbox.util.FileUtil;
import dorkbox.util.LZMA;
import dorkbox.util.LocationResolver;
import dorkbox.util.OS;
import dorkbox.util.Sys;
import dorkbox.util.annotation.AnnotationDefaults;
import dorkbox.util.annotation.AnnotationDetector;
import dorkbox.util.properties.PropertiesProvider;
public class Build {
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface Builder {
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface Configure {
}
public static final String BUILD_MODE = "build";
/** Location where settings are stored */
public static PropertiesProvider settings = new PropertiesProvider(new File("settings.ini"));
private ByteClassloader classloader;
static {
Paths.setDefaultGlobExcludes("**/.svn/**, **/.git/**");
}
public static void main(String[] _args) {
for (int i=0;i<_args.length;i++) {
_args[i] = _args[i].toLowerCase();
}
if (_args.length < 2) {
System.err.println("You must specify an action, followed by what you want done.");
System.err.println("For example: build myProject , which will then find and build your project");
return;
}
SimpleArgs args = new SimpleArgs(_args);
System.err.println("Dorkbox OAK: starting " + args);
Build build = new Build();
try {
build.prepareXcompile();
build.loadBuildInfo(args);
build.start(args);
} catch (Throwable e) {
e.printStackTrace();
}
}
// loads the build.oak file information
private void loadBuildInfo(SimpleArgs args) throws Exception {
HashMap<String, Object> data = BuildParser.parse(args);
Paths classPaths = BuildParser.getPathsFromMap(data, "classpath");
Paths sourcePaths = BuildParser.getPathsFromMap(data, "source");
// always use these as the default. don't want the runtimes on our path
classPaths.glob("libs", "**/*.jar", "!jdkRuntimes");
String projectName = "project";
if (data.containsKey("name")) {
Object object = data.get("name");
projectName = (String) object;
}
ByteClassloader bytesClassloader = new ByteClassloader(Thread.currentThread().getContextClassLoader());
ProjectJava project = ProjectJava.create(projectName)
.classPath(classPaths)
.compilerClassloader(bytesClassloader)
.sourcePath(sourcePaths);
try {
log().println("-= Compiling build instructions =-" + OS.LINE_SEPARATOR);
BuildLog.stop();
project.forceBuild(new BuildOptions(), false, false);
ProjectBasics.reset();
BuildLog.start();
} catch (Exception e) {
BuildLog.start();
throw e;
}
this.classloader = bytesClassloader;
}
private Build() {
}
public static BuildLog log() {
return new BuildLog();
}
public static BuildLog log(PrintStream printer) {
return new BuildLog(printer);
}
private void start(SimpleArgs args) throws IOException, IllegalAccessException, IllegalArgumentException,
InvocationTargetException, InstantiationException {
BuildOptions buildOptions = new BuildOptions();
List<Class<?>> controllers = AnnotationDetector.scan(this.classloader, new ClassByteIterator(this.classloader, null))
.forAnnotations(Build.Configure.class)
.collect(AnnotationDefaults.getType);
if (controllers != null) {
// do we have something to control the build process??
// now we want to update/search for all project builders if we didn't already run our specific builder
for (Class<?> c : controllers) {
Class<?>[] params = new Class<?>[] {BuildOptions.class, SimpleArgs.class};
Method buildTargeted = null;
// setup(BuildOptions, Args)
try {
buildTargeted = c.getMethod("setup", params);
} catch (Exception e) {}
if (buildTargeted != null) {
Object newInstance = c.newInstance();
// see if we can build a targeted build
buildTargeted.invoke(newInstance, buildOptions, args);
break;
}
}
}
// now we want to update/search for all project builders.
if (args.getMode().equals(Build.BUILD_MODE)) {
boolean found = false;
List<Class<?>> builders = AnnotationDetector.scan(this.classloader, new ClassByteIterator(this.classloader, null))
.forAnnotations(Build.Builder.class)
.collect(AnnotationDefaults.getType);
if (builders != null) {
String projectToBuild = args.get(1);
for (Class<?> c : builders) {
String simpleName = c.getSimpleName().toLowerCase();
if (projectToBuild.equals(simpleName)) {
Method build = null;
// 4 different build methods supported.
// build()
try {
build = c.getMethod(Build.BUILD_MODE, new Class<?>[] {});
} catch (Exception e) {}
if (build != null) {
build .invoke(c);
found = true;
break;
}
// build(Args)
Class<?>[] params = new Class<?>[] {SimpleArgs.class};
try {
build = c.getMethod(Build.BUILD_MODE, params);
} catch (Exception e) {}
if (build != null) {
build .invoke(c, args);
found = true;
break;
}
// build(BuildOptions)
params = new Class<?>[] {BuildOptions.class};
try {
build = c.getMethod(Build.BUILD_MODE, params);
} catch (Exception e) {}
if (build != null) {
build.invoke(c, buildOptions);
found = true;
break;
}
// build(BuildOptions, Args)
params = new Class<?>[] {BuildOptions.class, SimpleArgs.class};
try {
build = c.getMethod(Build.BUILD_MODE, params);
} catch (Exception e) {}
if (build != null) {
build .invoke(c, buildOptions, args);
found = true;
break;
}
}
}
}
if (!found) {
System.err.println("Unable to find a build for the target: " + args);
}
}
if (controllers != null) {
// do we have something to control the build process??
// now we want to update/search for all project builders if we didn't already run our specific builder
for (Class<?> c : controllers) {
Class<?>[] params = new Class<?>[] {BuildOptions.class, SimpleArgs.class};
Method buildTargeted = null;
// finish(BuildOptions, Args)
try {
buildTargeted = c.getMethod("takedown", params);
} catch (Exception e) {}
if (buildTargeted != null) {
Object newInstance = c.newInstance();
// see if we can build a targeted build
buildTargeted.invoke(newInstance, buildOptions, args);
break;
}
}
}
}
/**
* check to see if our jdk files have been decompressed (necessary for cross target builds)
*/
private void prepareXcompile() throws IOException {
String jdkDist = FileUtil.normalizeAsFile(Build.path("libs", "jdkRuntimes"));
List<File> jdkFiles = FileUtil.parseDir(jdkDist);
boolean first = true;
for (File f : jdkFiles) {
// unLZMA + unpack200
String name = f.getName();
String suffix = ".pack.lzma";
if (name.endsWith(suffix)) {
int nameLength = f.getAbsolutePath().length();
String fixedName = f.getAbsolutePath().substring(0, nameLength - suffix.length());
File file = new File(fixedName);
if (!file.canRead() || file.length() == 0) {
if (first) {
first = false;
System.err.println("******************************************");
System.err.println("* Dorkbox OAK -- Preparing environment *");
System.err.println("******************************************");
}
System.err.println("* Decompressing: " + f.getAbsolutePath());
InputStream inputStream = new FileInputStream(f);
// now uncompress
ByteArrayOutputStream outputStream = LZMA.decode(inputStream);
// now unpack
inputStream = new ByteArrayInputStream(outputStream.toByteArray());
outputStream = Pack200Util.Java.unpack200((ByteArrayInputStream) inputStream);
// now write to disk
inputStream = new ByteArrayInputStream(outputStream.toByteArray());
FileOutputStream fileOutputStream = new FileOutputStream(new File(fixedName));
Sys.copyStream(inputStream, fileOutputStream);
Sys.close(fileOutputStream);
}
}
}
if (!first) {
System.err.println("* Finished preparing environment");
System.err.println("******************************************\n\n");
}
}
public static String path(String... paths) {
StringBuilder buffer = new StringBuilder(128);
for (String p : paths) {
buffer.append(p).append(File.separator);
}
int length = buffer.length();
buffer.delete(length-1, length);
return buffer.toString();
}
/**
* Converts a class to it's .java file.
*/
public static Paths getClassPath(Class<?> clazz) throws IOException {
String rootPath = LocationResolver.get(clazz).getAbsolutePath();
String fileName = clazz.getCanonicalName();
String convert = fileName.replace('.', File.separatorChar) + ".java";
File rootFile = new File(rootPath);
if (rootFile.isDirectory()) {
File location = rootFile.getParentFile();
location = new File(location, "src");
Paths path = new Paths(location.getAbsolutePath(), convert);
return path;
} else {
throw new IOException("we can only support listing files that are not in a container!");
}
}
/**
* Gets all of the .java files accessible which belong to the
* package and subpackages of the given class
*/
public static Paths getClassPathPackage(Class<?> clazz) throws IOException {
String rootPath = LocationResolver.get(clazz).getAbsolutePath();
String dirName = clazz.getPackage().getName();
String convert = dirName.replace('.', File.separatorChar);
File rootFile = new File(rootPath);
if (rootFile.isDirectory()) {
File location = rootFile.getParentFile();
location = new File(location, "src");
location = new File(location, convert);
Paths paths = new Paths(location.getAbsolutePath(), "**.java");
return paths;
} else {
throw new IOException("we can only support listing class path packages that are not in a container!");
}
}
public static final void finish(String text) {
System.err.println("\n\n");
System.err.println("TIME: " + new Date());
System.err.println("FINISHED: " + text);
}
public static File moveFile(String source, String target) throws IOException {
source = FileUtil.normalizeAsFile(source);
target = FileUtil.normalizeAsFile(target);
log().title(" Moving file").message(" ╭─ " + source,
"╰─> " + target);
return FileUtil.moveFile(source, target);
}
public static File copyFile(File source, File target) throws IOException {
source = FileUtil.normalize(source);
target = FileUtil.normalize(target);
log().title(" Copying file").message(" ╭─ " + source.getAbsolutePath(),
"╰─> " + target.getAbsolutePath());
return FileUtil.copyFile(source, target);
}
public static void copyFile(String source, String target) throws IOException {
source = FileUtil.normalizeAsFile(source);
target = FileUtil.normalizeAsFile(target);
log().title(" Copying file").message(" ╭─ " + source,
"╰─> " + target);
FileUtil.copyFile(source, target);
}
public static void copyDirectory(String source, String target, String... dirNamesToIgnore) throws IOException {
source = FileUtil.normalizeAsFile(source);
target = FileUtil.normalizeAsFile(target);
log().title(" Copying dir").message(" ╭─ " + source,
"╰─> " + target);
FileUtil.copyDirectory(source, target, dirNamesToIgnore);
}
}

View File

@ -0,0 +1,180 @@
/*
* Copyright 2012 dorkbox, llc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dorkbox;
public class BuildOptions {
/**
* Options that affect the compilation of the project
*/
public static class Compiler {
/**
* Do we want to force a rebuild of the project?
*/
public boolean forceRebuild = false;
/**
* enables PACK200+LZMA+GZIP+ENCRYPTION on jar contents. Since this is
* REALLY SLOW (creating and running), we don't always want to do this.
*/
public boolean release = false;
/**
* we want debugging enabled (until release!)
*/
public boolean debugEnabled = true;
/**
* if we are debug mode, do we want to disable certain actions to make compiling faster?
*/
public boolean enableDebugSpeedImprovement = false;
/**
* Suppress sun warnings during the compile stage. ONLY enable this is you know what you are doing in your project!
*/
public boolean suppressSunWarnings = false;
/**
* what version do we want to compile java for?
*
* when compiling for java 1.6, you MUST specify the 1.6 rt.jar location
* Also, when compiling GWT, this has no effect
*/
public int targetJavaVersion = 7;
/**
* this is only necessary when building for lesser versions of java than you are currently running
* (for example, compiling for 1.6, when compiling on 1.7).
* <p>
* This is meant to be overridden for custom build locations
*/
public CrossCompilerLibrary crossCompileLibrary = new CrossCompilerLibrary();
/**
* US export controls require that the JVM cannot perform AES-256 crypto. Here we are able to control the JCE policy files to
* to permit unlimited crypto if we want to (and are following US export controls)
*/
public boolean unlimitedJceCrpytoRuntime = true;
/**
* Adds the "verbose" compile option. This is useful if you want to get a list (from the compiler) of EVERY CLASS compiled/used
*/
public boolean enableCompilerTrace = false;
/**
* Provide the location of the rt.jar libraries for 'cross compiling' to a different java target.
* <p>
* This is meant to be overridden for custom locations.
*/
public static class CrossCompilerLibrary {
public CrossCompilerLibrary() {
}
/** Please note that the binary release is GLPv2 + Classpath Exception, giving us permission to use it to compile binaries */
public String getCrossCompileLibraryLocation(int targetVersion) {
return Build.path("libs", "jdkRuntimes", "openJdk" + targetVersion + "_rt.jar");
}
}
}
/**
* Options that affect how the launcher is included, and how the jar is signed/encrypted
*/
public static class Launcher {
/**
* do we want to enable the launcher crypto signature verification? (runtime requires this)
*/
public boolean crypto = true;
/**
* do we want to deploy the JAVA runtime as a part of our app? (depends on crypto to work)
*/
public boolean runtime = true;
/**
* do we want to enable the key/mouse input monitor?
*/
public boolean monitor = true;
/**
* do we want to enable the socket bind wrapper? (when you run launcher as root, it will drop root when runnning java)
*/
public boolean bindWrapper = true;
/**
* do we want to enable LGPL parsing of the RESOURCES.BOX file?
*/
public boolean lpgl = false;
}
/**
* Misc libraries to include (which are not easy to just link the library)
*/
public static class Misc {
/**
* Java7 (but not ARM) can have the optional JavaFX library included.
*/
public boolean includeJavaFx = false;
}
public Compiler compiler = new Compiler();
public Launcher launcher = new Launcher();
public Misc misc = new Misc();
/**
* Gets the executable name based on what different build options are specified.
*/
public String getExecutableName(String exectuableBaseName) {
if (this.launcher.runtime && !this.launcher.crypto) {
throw new RuntimeException("Unable to deply runtime with crypto disabled! You must enable crypto to continue!");
}
String newName = exectuableBaseName;
if (this.compiler.debugEnabled) {
newName += "_debug";
}
if (this.launcher.lpgl) {
newName += "_lgpl";
}
if (this.launcher.crypto) {
newName += "_crypto";
}
if (this.launcher.runtime) {
newName += "_runtime";
}
if (this.launcher.monitor) {
newName += "_monitor";
}
if (this.launcher.bindWrapper) {
newName += "_bind";
}
return newName;
}
/**
* @return the target java version to compile, in full format. IE: "1.6", or "1.7"
*/
public String getTargetVersion() {
return "1."+this.compiler.targetJavaVersion;
}
}

View File

@ -0,0 +1,337 @@
/*
* Copyright 2012 dorkbox, llc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dorkbox.build;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.bouncycastle.crypto.digests.MD5Digest;
import com.esotericsoftware.wildcard.Paths;
import com.twmacinta.util.MD5;
import dorkbox.Build;
import dorkbox.BuildOptions;
import dorkbox.util.Base64Fast;
import dorkbox.util.FileUtil;
public abstract class ProjectBasics {
public static final String NO_PATH_TOKEN = "NO_PATH_TOKEN";
public static final String Java_Pattern = "**" + File.separator + "*.java";
public static final String Jar_Pattern = "**" + File.separator + "*.jar";
public static final String STAGING = "staging";
public static Map<String, ProjectBasics> deps = new LinkedHashMap<String, ProjectBasics>();
private static Set<String> buildList = new HashSet<String>();
private static boolean forceRebuild = false;
private static boolean alreadyChecked = false;
public static List<File> builderFiles = new ArrayList<File>();
{
// check to see if our deploy code has changed. if yes, then we have to rebuild everything since
// we don't know what might have changed.
Paths paths = new Paths();
File file = new File(ProjectBasics.class.getSimpleName() + ".java").getAbsoluteFile().getParentFile();
paths.glob(file.getAbsolutePath(), Java_Pattern);
for (File f : builderFiles) {
paths.glob(f.getAbsolutePath(), Java_Pattern);
}
try {
String oldHash = Build.settings.get("BUILD", String.class);
String hashedContents = generateChecksums(paths);
if (oldHash != null) {
if (!oldHash.equals(hashedContents)) {
forceRebuild = true;
}
} else {
forceRebuild = true;
}
if (forceRebuild) {
if (!alreadyChecked) {
alreadyChecked = true;
System.err.println("-= Build system changed. Rebuilding =-");
}
Build.settings.save("BUILD", hashedContents);
}
} catch (IOException e) {
}
}
// removes all saved checksums as well as dependencies. Used to "reset everything", similar to if it was relaunched.
public static void reset() {
deps.clear();
buildList.clear();
}
public String name;
protected Paths extraFiles = new Paths();
public String outputFile;
public String outputDir;
protected Set<String> dependencies;
private transient Paths checksumPaths = new Paths();
public static ProjectBasics get(String projectName) {
if (deps.containsKey(projectName)) {
ProjectBasics project = deps.get(projectName);
// put swt lib into jar!
return project;
} else {
throw new IllegalArgumentException(projectName + " project must exist!");
}
}
public static void buildAll(BuildOptions properties) throws Exception {
for (ProjectBasics project : deps.values()) {
ProjectBasics.build(project, properties);
}
}
public static void build(String projectName, BuildOptions properties) throws Exception {
ProjectBasics project = get(projectName);
if (project != null) {
project.build(properties);
} else {
System.err.println("Project is NULL. Aborting build.");
}
}
public static void build(ProjectBasics project, BuildOptions properties) throws Exception {
project.build(properties);
}
public static void remove(String outputDir) {
deps.remove(outputDir);
}
protected ProjectBasics(String projectName) {
this.name = projectName;
String lowerCase_outputDir = projectName.toLowerCase();
this.outputDir = FileUtil.normalizeAsFile(STAGING + File.separator + lowerCase_outputDir);
String outputFile = lowerCase_outputDir.substring(lowerCase_outputDir.lastIndexOf("/") + 1, lowerCase_outputDir.length());
this.outputFile = outputFile + getExtension();
}
public ProjectBasics depends(String dependsProjectName) {
if (dependsProjectName == null) {
throw new NullPointerException("Dependencies cannot be null!");
}
if (this.dependencies == null) {
this.dependencies = new HashSet<String>(2);
}
this.dependencies.add(dependsProjectName);
return this;
}
public ProjectBasics output() {
String lowerCase_outputDir = this.outputDir.toLowerCase();
this.outputDir = STAGING + File.separator + lowerCase_outputDir;
String outputFile = lowerCase_outputDir.substring(lowerCase_outputDir.lastIndexOf("/") + 1, lowerCase_outputDir.length());
this.outputFile = outputFile + getExtension();
return this;
}
/**
* Checks to see if we already built this project. Also, will automatically build this projects
* dependencies (if they haven't already been built).
*
* @return true if we can skip building this project
*/
protected boolean checkAndBuildDependencies(BuildOptions properties) throws Exception {
// exit early if we already built this project
if (buildList.contains(this.outputDir)) {
Build.log().message("Skipped (built this run)");
return true;
}
buildList.add(this.outputDir);
// ONLY build the dependencies as well
if (this.dependencies != null) {
for (String dep : this.dependencies) {
ProjectBasics project = deps.get(dep);
if (!buildList.contains(project.outputDir)) {
project.build(properties);
}
}
}
return false;
}
/** extra files to include when you jar the project */
public ProjectBasics extraFiles(Paths filePaths) {
this.extraFiles.add(filePaths);
return this;
}
protected abstract ProjectBasics build(BuildOptions properties) throws Exception;
protected abstract String getExtension();
/**
* Add a path to be checksum'd.
*/
public final void checksum(Paths path) {
this.checksumPaths.add(path);
}
/**
* @return true if the checksums for path match the saved checksums and the jar file exists
*/
boolean verifyChecksums(BuildOptions properties) throws IOException {
if (forceRebuild || properties.compiler.forceRebuild) {
return false;
}
// check to see if our SOURCES *and check-summed files* have changed.
String hashedContents = generateChecksums(this.checksumPaths);
String checkContents = Build.settings.get(this.name, String.class);
return hashedContents != null && hashedContents.equals(checkContents);
}
/**
* Saves the checksums for a given path
*/
void saveChecksums() throws IOException {
// hash/save the sources *and check-summed files* files
String hashedContents = generateChecksums(this.checksumPaths);
Build.settings.save(this.name, hashedContents);
}
/**
* Generates checksums for the given path
*/
public static final String generateChecksum(File file) throws IOException {
synchronized (ProjectBasics.class) {
// calculate the hash of file
boolean found = false;
if (file.isFile() && file.canRead()) {
found = true;
}
if (!found) {
return null;
}
byte[] hashBytes = MD5.getHash(file);
String fileChecksums = Base64Fast.encodeToString(hashBytes, false);
return fileChecksums;
}
}
/**
* Generates checksums for the given path
*/
public static final String generateChecksums(Paths... paths) throws IOException {
synchronized (ProjectBasics.class) {
// calculate the hash of all the files in the source path
Set<String> names = new HashSet<String>(64);
for (Paths path : paths) {
names.addAll(path.getPaths());
}
// hash of hash of files. faster than using java to hash files
MD5Digest md5_digest = new MD5Digest();
boolean found = false;
for (String name : names) {
File file = new File(name);
if (file.isFile() && file.canRead()) {
found = true;
byte[] hashBytes = MD5.getHash(file);
md5_digest.update(hashBytes, 0, hashBytes.length);
}
}
if (!found) {
return null;
}
byte[] hashBytes = new byte[md5_digest.getDigestSize()];
md5_digest.doFinal(hashBytes, 0);
String fileChecksums = Base64Fast.encodeToString(hashBytes, false);
return fileChecksums;
}
}
@Override
public String toString() {
return this.name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (this.name == null ? 0 : this.name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
ProjectBasics other = (ProjectBasics) obj;
if (this.name == null) {
if (other.name != null) {
return false;
}
} else if (!this.name.equals(other.name)) {
return false;
}
return true;
}
}

View File

@ -0,0 +1,398 @@
/*
* Copyright 2012 dorkbox, llc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dorkbox.build;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.Arrays;
import java.util.List;
import java.util.Map.Entry;
import com.esotericsoftware.wildcard.Paths;
import dorkbox.Build;
import dorkbox.BuildOptions;
import dorkbox.build.util.jar.JarUtil;
import dorkbox.util.FileUtil;
import dorkbox.util.gwt.GwtSymbolMapParser;
import dorkbox.util.process.JavaProcessBuilder;
public class ProjectGwt extends ProjectBasics {
private String[] options;
private String projectLocation;
protected Paths sourcePaths = new Paths();
public static ProjectGwt create(String projectName, String projectLocation) {
ProjectGwt project = new ProjectGwt(projectName, projectLocation);
deps.put(projectName, project);
return project;
}
protected ProjectGwt(String projectName, String projectLocation) {
super(projectName);
this.projectLocation = projectLocation;
checksum(this.sourcePaths);
}
public ProjectGwt sourcePath(Paths sourcePaths) {
if (sourcePaths == null) {
throw new NullPointerException("Source paths cannot be null!");
}
this.sourcePaths.add(sourcePaths);
return this;
}
public ProjectGwt sourcePath(String srcDir) {
if (srcDir.endsWith("src")) {
String parent = new File(srcDir).getAbsoluteFile().getParent();
checksum(new Paths(parent));
}
return sourcePath(new Paths(srcDir, "./"));
}
public ProjectGwt sourcePath(String dir, String... patterns) {
return sourcePath(new Paths(dir, patterns));
}
/**
* GWT only cares about the output dir (it doesn't make jars for compiling)
* @return true if the checksums for path match the saved checksums and the jar file exists
*/
boolean verifyChecksums(ProjectBasics project, BuildOptions properties) throws IOException {
boolean sourceHashesSame = super.verifyChecksums(properties);
if (!sourceHashesSame) {
return false;
}
// if the sources are the same, check the output dir
String fileName = project.outputDir;
File file = new File(fileName);
if (file.exists()) {
String dirChecksum = generateChecksum(file);
String checkContents = Build.settings.get(fileName, String.class);
return dirChecksum != null && dirChecksum.equals(checkContents);
}
return true;
}
/**
* GWT only cares about the output dir (it doesn't make jars for compiling)
* Saves the checksums for a given path
*/
@Override
void saveChecksums() throws IOException {
super.saveChecksums();
// hash/save the output files (if there are any)
String fileName = this.outputDir;
File file = new File(fileName);
if (file.exists()) {
String fileChecksum = generateChecksum(file);
Build.settings.save(fileName, fileChecksum);
}
}
/**
* This uses the same gwt symbol parser as the web-server project.
*/
@Override
protected ProjectGwt build(BuildOptions properties) throws Exception {
// exit early if we already built this project
if (checkAndBuildDependencies(properties)) {
return this;
}
boolean shouldBuild = false;
try {
// GWT checksum requirements are different than regular java.
shouldBuild = !verifyChecksums(properties);
if (shouldBuild) {
// make sure our dependencies are on the classpath.
if (this.dependencies != null) {
for (String dep : this.dependencies) {
ProjectBasics project = deps.get(dep);
this.sourcePaths.glob(STAGING, project.outputFile);
}
}
FileUtil.delete(this.outputDir);
FileUtil.mkdir(this.outputDir);
String clientString = "Client";
String stagingWar = Build.path(STAGING, "war");
String stagingWarWebINF = Build.path(stagingWar, "WEB-INF");
String stagingWarWebINFDeploy = Build.path(stagingWarWebINF, "deploy");
String stagingJunk = Build.path(STAGING, "junk");
String stagingUnitCache = Build.path(STAGING, "gwt-unitCache");
String stagingSymbols = Build.path(STAGING, "symbolMaps");
String clientTempLocation = Build.path(STAGING, clientString + "_javascript");
String srcWarPath = Build.path("..", this.projectLocation, "war");
// make the output directory
FileUtil.delete(stagingWar);
FileUtil.delete(stagingSymbols);
FileUtil.delete(clientTempLocation);
FileUtil.mkdir(stagingWar);
FileUtil.mkdir(stagingUnitCache);
if (properties.compiler.release) {
FileUtil.delete(stagingUnitCache);
}
System.err.println("Compiling GWT modules. This can take a while....");
System.err.println(" Working location: " + FileUtil.normalize(new File("test")).getParent());
JavaProcessBuilder builder = new JavaProcessBuilder(System.in, System.out, System.err);
builder.setMaximumHeapSizeInMegabytes(512);
// we want to DEBUG this! (figure out wtf is going on)
// builder.addJvmOption("-Xdebug");
// builder.addJvmOption("-Xrunjdwp:transport=dt_socket,server=y,address=1044");
builder.setMainClass("com.google.gwt.dev.Compiler");
// The Java classpath should include:
// - the Java source code of your application
// - gwt-dev.jar, gwt-user.jar,
// - any compiler-visible resources such as ui.xml and .png files,
// - and the COMPILED versions of any generators and linkers added or used by the build.
// the GWT compiler needs the source/parent directory of the XML files
builder.addJvmClasspaths(this.sourcePaths.getPaths());
// prevent phone-home of google GWT compiler
builder.addArgument("-XdisableUpdateCheck");
// EXPERIMENTAL: Disables some java.lang.Class methods (e.g. getName())
builder.addArgument("-XdisableClassMetadata");
//Logs output in a graphical tree view
builder.addArgument("-treeLogger");
// fail if there are any warnings
builder.addArgument("-strict");
// The directory into which deployable output files will be written (defaults to 'war')
builder.addArgument("-war " + stagingWar);
// we want the compiler to save the symbols map (so we can correctly do the mapping for message-bus de-obfuscation)
builder.addArgument("-deploy " + stagingWarWebINFDeploy);
// The directory into which extra files, not intended for deployment, will be written
builder.addArgument("-extra " + stagingJunk);
// Additional arguments like -style PRETTY/OBFuscated/DETAILED or -logLevel INFO/WARN/ERROR/TRACE/DEBUG/SPAM/ALL
// logLevel is log level during compile.
builder.addArgument("-logLevel INFO");
// builder.addArgument("-logLevel TRACE");
for (String option : this.options) {
builder.addArgument(option);
}
// DETAILED, PRETTY, OBF[USCATED]
if (properties.compiler.debugEnabled) {
// builder.addArgument("-style PRETTY");
builder.addArgument("-style DETAILED");
} else {
builder.addArgument("-style OBF");
}
if (properties.compiler.release) {
// generate the gwt cache files EVERY time
builder.addArgument("-Dgwt.usearchives=false");
}
// must be last
builder.addArgument("hive." + clientString);
builder.start();
// move the symbol maps to the correct spot
FileUtil.mkdir(stagingSymbols);
Paths symbolMapPaths = new Paths(Build.path(stagingWarWebINFDeploy, clientString, "symbolMaps"), "*.symbolMap");
for (File file : symbolMapPaths.getFiles()) {
// clean up the symbolmaps first!
parseAndCopyGwtSymbols(file, new File(Build.path(stagingSymbols, file.getName())));
}
// move the client generated javascript to the correct spot
FileUtil.moveDirectory(Build.path(stagingWar, clientString), clientTempLocation);
// remove directories that are not needed/wanted in the deployment
FileUtil.delete(stagingWar);
FileUtil.delete(stagingJunk);
if (properties.compiler.release) {
FileUtil.delete(stagingUnitCache);
}
// create the NEW war directory
FileUtil.mkdir(stagingWar);
// todo: pass in the hive-webclient project name somehow?
Paths warFiles = new Paths(srcWarPath, "*.html", "*.ico");
for (File file : warFiles.getFiles()) {
FileUtil.copyFile(file.getAbsolutePath(), Build.path(stagingWar, file.getName()));
}
// copy over images
FileUtil.copyDirectory(Build.path(srcWarPath, "images"), Build.path(stagingWar, "images"), ".svn");
// make the web-INF directory
FileUtil.mkdir(stagingWarWebINF);
// move the symbolMaps into the correct spot.
FileUtil.moveDirectory(stagingSymbols, Build.path(stagingWarWebINF, "symbolMaps"));
// add any extra files to the output war dir.
File warDir = new File(stagingWar);
List<String> paths = this.extraFiles.getPaths();
List<String> paths2 = this.extraFiles.getRelativePaths();
for (int i=0;i<paths.size();i++) {
String path = paths.get(i);
String dest = paths2.get(i);
FileUtil.copyFile(path, new File(warDir, dest).getPath());
}
// move the client generated javascript to the correct spot
FileUtil.moveDirectory(clientTempLocation, Build.path(stagingWar, clientString));
// war it up
warFiles = new Paths(stagingWar, "**");
List<String> fullPaths = warFiles.filesOnly().getPaths();
List<String> relativePaths = warFiles.filesOnly().getRelativePaths();
String warFilePath = Build.path(STAGING, this.outputFile);
File warFile = new File(warFilePath);
if (warFile.exists()) {
warFile.delete();
}
FileUtil.mkdir(warFile.getParent());
// make a jar (really a war file)
JarUtil.war(warFilePath, fullPaths, relativePaths);
// cleanup
FileUtil.delete(stagingWar);
// calculate the hash of all the files in the source path
saveChecksums();
} else {
Build.log().message("Skipped (nothing changed)");
}
} finally {
if (shouldBuild) {
FileUtil.delete(this.outputDir);
}
}
System.err.println(" Build success: " + this.outputDir);
return this;
}
public ProjectGwt options(String... options) {
if (this.options != null) {
List<String> origList = Arrays.asList(this.options);
List<String> newList = Arrays.asList(options);
origList.addAll(newList);
this.options = origList.toArray(new String[0]);
} else {
this.options = options;
}
return this;
}
/**
* Parses the relevant data from the symbol map and saves it in the specified file.
*/
public static void parseAndCopyGwtSymbols(File sourceFile, File destSymbolFile) throws IOException {
GwtSymbolMapParser parser = new GwtSymbolMapParser();
//FileReader always assumes default encoding is OK!
FileInputStream fileInputStream = new FileInputStream(sourceFile);
parser.parse(fileInputStream);
destSymbolFile.getParentFile().mkdirs();
Writer output = new BufferedWriter(new FileWriter(destSymbolFile));
try {
// FileWriter always assumes default encoding is OK
output.write("# BUILD-SCRIPT MODIFIED: only relevant symbols are present.\n");
StringBuilder stringBuilder = new StringBuilder();
for (Entry<String, String> entry : parser.getSymbolMap().entrySet()) {
stringBuilder.delete(0, stringBuilder.capacity());
// create a "shrunk" version for deployment. This is marginally better than the original version
stringBuilder
.append(entry.getKey()) // jsName
.append(",")
.append(entry.getValue()) // java className
.append("\n");
String line = stringBuilder.toString();
// FileWriter always assumes default encoding is OK
output.write(line);
}
} finally {
output.close();
}
}
@Override
protected String getExtension() {
return ".war";
}
}

View File

@ -0,0 +1,512 @@
/*
* Copyright 2012 dorkbox, llc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dorkbox.build;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import javax.tools.Diagnostic;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import com.esotericsoftware.wildcard.Paths;
import com.esotericsoftware.yamlbeans.YamlConfig;
import com.esotericsoftware.yamlbeans.YamlException;
import com.esotericsoftware.yamlbeans.YamlWriter;
import com.esotericsoftware.yamlbeans.scalar.ScalarSerializer;
import dorkbox.Build;
import dorkbox.BuildOptions;
import dorkbox.build.util.ByteClassloader;
import dorkbox.build.util.JavaMemFileManager;
import dorkbox.build.util.PreJarAction;
import dorkbox.build.util.jar.JarOptions;
import dorkbox.build.util.jar.JarSigner;
import dorkbox.build.util.jar.JarUtil;
import dorkbox.license.License;
import dorkbox.license.LicenseType;
import dorkbox.util.FileUtil;
import dorkbox.util.OS;
public class ProjectJava extends ProjectBasics {
protected ArrayList<String> extraArgs;
protected Paths sourcePaths = new Paths();
public Paths classPaths = new Paths();
private boolean includeSource;
public List<License> licenses = new ArrayList<License>();
private transient PreJarAction preJarAction;
private Class<?> mainClass;
private ByteClassloader bytesClassloader = null;
public static ProjectJava create(String projectName) {
ProjectJava project = new ProjectJava(projectName);
deps.put(projectName, project);
return project;
}
public ProjectJava(String projectName) {
super(projectName);
checksum(this.sourcePaths);
checksum(this.classPaths);
}
public ProjectJava sourcePath(Paths sourcePaths) {
if (sourcePaths == null) {
throw new NullPointerException("Source paths cannot be null!");
}
this.sourcePaths.add(sourcePaths);
// ALWAYS add the source paths to be checksumed!
checksum(sourcePaths);
return this;
}
public ProjectJava sourcePath(String srcDir) {
if (srcDir.endsWith("src")) {
String parent = new File(srcDir).getAbsoluteFile().getParent();
checksum(new Paths(parent));
}
return sourcePath(new Paths(srcDir, "./"));
}
public ProjectJava sourcePath(String dir, String... patterns) {
return sourcePath(new Paths(dir, patterns));
}
public ProjectJava classPath(Paths classPaths) {
if (classPaths == null) {
throw new NullPointerException("Class paths cannot be null!");
}
this.classPaths.add(classPaths);
return this;
}
public ProjectJava classPath(String dir, String... patterns) {
return classPath(new Paths(dir, patterns));
}
/** extra files to include when you jar the project */
@Override
public ProjectJava extraFiles(Paths filePaths) {
super.extraFiles(filePaths);
return this;
}
@Override
public final ProjectJava depends(String dependsProjectName) {
super.depends(dependsProjectName);
return this;
}
@Override
public ProjectJava output() {
String lowerCase_outputDir = this.outputDir.toLowerCase();
this.outputDir = STAGING + File.separator + lowerCase_outputDir;
String outputFile = lowerCase_outputDir.substring(lowerCase_outputDir.lastIndexOf("/") + 1, lowerCase_outputDir.length());
this.outputFile = outputFile + getExtension();
return this;
}
public ProjectJava addArg(String arg) {
if (this.extraArgs == null) {
this.extraArgs = new ArrayList<String>();
}
this.extraArgs.add(arg);
return this;
}
@Override
protected ProjectJava build(BuildOptions properties) throws Exception {
return build(properties, true, true, false, null);
}
/** always does a build, ignoring checksums */
public void forceBuild(BuildOptions options) throws Exception {
forceBuild(options, false, false);
}
/** always does a build, ignoring checksums */
public void forceBuild(BuildOptions options, boolean deleteCompiledOnComplete, boolean buildJar) throws Exception {
File file = FileUtil.normalize(new File(STAGING + File.separator + this.outputFile));
if (file.exists()) {
FileUtil.delete(file);
}
File dir = new File(this.outputDir);
if (dir.exists()) {
FileUtil.delete(dir);
}
Build.settings.remove(this.outputDir);
build(options, deleteCompiledOnComplete, buildJar, false, null);
}
// (and add them to the classpath)
protected ProjectJava build(BuildOptions options, boolean deleteOnComplete, boolean buildJar,
boolean signJar, String signName) throws Exception {
Build.log().message();
Build.log().title(" Building").message(this.name, "Output - " + this.outputDir);
// exit early if we already built this project
if (checkAndBuildDependencies(options)) {
return this;
}
boolean shouldBuild = !verifyChecksums(this, options);
if (shouldBuild) {
// barf if we don't have source files!
if (this.sourcePaths.getFiles().isEmpty()) {
throw new RuntimeException("No source files specified for project: " + this.name);
}
// make sure our dependencies are on the classpath.
if (this.dependencies != null) {
for (String dep : this.dependencies) {
ProjectBasics project = deps.get(dep);
this.classPaths.glob(STAGING, project.outputFile);
}
}
compile(this.sourcePaths, this.classPaths, this.outputDir, options);
Build.log().message("Compile success.");
if (buildJar) {
if (this.preJarAction != null) {
Build.log().message("Running action before Jar is created...");
this.preJarAction.executeBeforeJarHappens(this.outputDir);
}
JarOptions jarOptions = new JarOptions();
jarOptions.outputFile = STAGING + File.separator + this.outputFile;
jarOptions.inputPaths = new Paths(this.outputDir);
jarOptions.extraPaths = this.extraFiles;
if (this.mainClass != null) {
jarOptions.mainClass = this.mainClass.getCanonicalName();
jarOptions.classpath = this.classPaths;
}
if (this.includeSource) {
jarOptions.sourcePaths = this.sourcePaths;
}
if (!this.licenses.isEmpty()) {
jarOptions.licenses = this.licenses;
}
jarOptions.createDebugVersion = options.compiler.debugEnabled;
JarUtil.jar(jarOptions);
if (signJar) {
JarSigner.sign(this.outputFile, signName);
}
// calculate the hash of all the files in the source path
saveChecksums();
}
} else {
Build.log().message("Skipped (nothing changed)");
}
if (shouldBuild && deleteOnComplete) {
FileUtil.delete(this.outputDir);
}
return this;
}
/**
* @return true if the checksums for path match the saved checksums and the jar file exists
*/
boolean verifyChecksums(ProjectBasics project, BuildOptions properties) throws IOException {
boolean sourceHashesSame = super.verifyChecksums(properties);
if (!sourceHashesSame) {
return false;
}
// if the sources are the same, check the jar file
String fileName = project.outputDir;
fileName += project.getExtension();
File file = new File(fileName);
if (file.exists()) {
String jarChecksum = generateChecksum(file);
String checkContents = Build.settings.get(fileName, String.class);
return jarChecksum != null && jarChecksum.equals(checkContents);
} else {
// output dir was removed
return false;
}
}
/**
* Saves the checksums for a given path
*/
@Override
void saveChecksums() throws IOException {
super.saveChecksums();
// hash/save the jar file (if there was one)
String fileName = this.outputDir;
fileName += getExtension();
File file = new File(fileName);
if (file.exists()) {
String fileChecksum = generateChecksum(file);
Build.settings.save(fileName, fileChecksum);
}
}
/**
* Compiles into class files.
*/
public void compile(Paths source, Paths classpath, String outputDir, BuildOptions buildOptions) throws IOException {
// if you get messages, such as
// warning: [path] bad path element "/x/y/z/lib/fubar-all.jar": no such file or directory
// That is because that file exists in a MANIFEST.MF somewhere on the classpath! Find the jar that has that, and rip out
// the offending manifest.mf file.
// see: http://stackoverflow.com/questions/1344202/bad-path-warning-where-is-it-coming-from
if (source.isEmpty()) {
throw new IOException("No source files found.");
}
FileUtil.delete(outputDir);
FileUtil.mkdir(outputDir);
ArrayList<String> args = new ArrayList<String>();
if (buildOptions.compiler.enableCompilerTrace) {
// TODO: Interesting to note, that when COMPILING this with verbose, we can get a list (from the compiler) of EVERY CLASS NEEDED
// to run our application! This would be useful in "trimming" the necessary files needed by the JVM.
args.add("-verbose");
}
if (buildOptions.compiler.debugEnabled) {
Build.log().message("Adding debug info.");
args.add("-g"); // Generate all debugging information, including local variables. By default, only line number and source file information is generated.
} else {
args.add("-g:none");
}
args.add("-d");
args.add(outputDir);
args.add("-encoding");
args.add("UTF-8");
if (OS.getJavaVersion() > buildOptions.compiler.targetJavaVersion) {
Build.log().message("Building cross-platform target!");
// if our runtime env. is NOT equal to our target env.
args.add("-source");
args.add(buildOptions.getTargetVersion());
args.add("-target");
args.add(buildOptions.getTargetVersion());
args.add("-bootclasspath");
args.add(buildOptions.compiler.crossCompileLibrary.getCrossCompileLibraryLocation(buildOptions.compiler.targetJavaVersion));
}
// suppress sun proprietary warnings
if (buildOptions.compiler.suppressSunWarnings) {
args.add("-XDignore.symbol.file");
}
if (this.extraArgs != null) {
boolean extraArgsHaveXlint = false;
for (String arg : this.extraArgs) {
if (arg.startsWith("-Xlint")) {
extraArgsHaveXlint = true;
break;
}
}
if (!extraArgsHaveXlint) {
args.add("-Xlint:all");
}
// add any extra arguments
args.addAll(this.extraArgs);
}
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
if (compiler == null) {
throw new RuntimeException("No compiler available. Ensure you are running from a JDK, and not a JRE.");
}
if (classpath != null && !classpath.isEmpty()) {
args.add("-classpath");
args.add(classpath.toString(File.pathSeparator));
}
// now compile the code
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
JavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
try {
Iterable<? extends JavaFileObject> javaFileObjectsFromFiles;
if (this.bytesClassloader == null) {
javaFileObjectsFromFiles = ((StandardJavaFileManager)fileManager).getJavaFileObjectsFromFiles(source.getFiles());
} else {
fileManager = new JavaMemFileManager((StandardJavaFileManager)fileManager, this.bytesClassloader);
((JavaMemFileManager)fileManager).setSource(source);
javaFileObjectsFromFiles = ((JavaMemFileManager)fileManager).getSourceFiles();
}
compiler.getTask(null, fileManager, diagnostics, args, null,
javaFileObjectsFromFiles).call();
} finally {
fileManager.close();
}
boolean hasError = false;
for (@SuppressWarnings("rawtypes") Diagnostic diagnostic : diagnostics.getDiagnostics()) {
if (diagnostic.getKind() == javax.tools.Diagnostic.Kind.ERROR) {
hasError = true;
break;
}
}
if (hasError) {
StringBuilder buffer = new StringBuilder(1024);
for (@SuppressWarnings("rawtypes") Diagnostic diagnostic : diagnostics.getDiagnostics()) {
if (buffer.length() > 0) {
buffer.append("\n");
}
buffer.append("Line ").append(diagnostic.getLineNumber()).append(": ");
buffer.append(diagnostic.getMessage(null));
}
throw new RuntimeException("Compilation errors:\n" + buffer);
}
compiler = null;
System.gc();
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
}
}
@Override
protected String getExtension() {
return ".jar";
}
public static interface OnJarEntryAction {
boolean canHandle(String fileName);
int onEntry(String fileName, ByteArrayInputStream inputStream, OutputStream output) throws Exception;
}
public ProjectJava includeSourceInJar() {
this.includeSource = true;
return this;
}
public ProjectJava license(License license) {
this.licenses.add(license);
return this;
}
public ProjectJava license(List<License> licenses) {
this.licenses.addAll(licenses);
return this;
}
/** Actions that might need to take place before the project is jar'd */
public ProjectJava preJarAction(PreJarAction preJarAction) {
this.preJarAction = preJarAction;
return this;
}
/**
* Specify the main class.
*/
public ProjectJava mainClass(Class<?> clazz) {
this.mainClass = clazz;
return this;
}
/**
* Take all of the parameters of this project, and convert it to a text file.
* @throws IOException
*/
public void toBuildFile() throws IOException {
YamlWriter writer = new YamlWriter(new FileWriter("build.oak"));
YamlConfig config = writer.getConfig();
config.writeConfig.setWriteRootTags(false);
config.setPropertyElementType(ProjectJava.class, "licenses", License.class);
config.setPrivateFields(true);
config.readConfig.setConstructorParameters(License.class, new Class[]{String.class, LicenseType.class}, new String[] {"licenseName", "licenseType"});
config.readConfig.setConstructorParameters(ProjectJava.class, new Class[]{String.class}, new String[] {"projectName"});
config.setScalarSerializer(Paths.class, new ScalarSerializer<Paths>() {
@Override
public Paths read (String value) throws YamlException {
String[] split = value.split(File.pathSeparator);
Paths paths = new Paths();
for (String s : split) {
paths.addFile(s);
}
return paths;
}
@Override
public String write (Paths paths) throws YamlException {
return paths.toString(File.pathSeparator);
}
});
writer.write(this);
writer.close();
}
/**
* The specified byte loading classloader to save the compiled class bytes into,
*/
public ProjectJava compilerClassloader(ByteClassloader bytesClassloader) {
this.bytesClassloader = bytesClassloader;
return this;
}
}

View File

@ -0,0 +1,77 @@
/*
* Copyright 2012 dorkbox, llc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dorkbox.build;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;
public class SimpleArgs {
private final Set<String> argsAsSet;
private final String[] args;
private int lastIndex = 0;
public SimpleArgs(String[] args) {
this.args = args;
this.argsAsSet = new HashSet<String>(args.length);
for (int i = 0; i < args.length; i++) {
String arg = args[i];
String lowerCase = arg.toLowerCase(Locale.US);
this.argsAsSet.add(lowerCase);
}
}
public boolean has(String argToCheck) {
String argToCheck2 = argToCheck.toLowerCase(Locale.US);
return this.argsAsSet.contains(argToCheck2);
}
public String get(String argToCheck) {
String argToCheck2 = argToCheck.toLowerCase(Locale.US);
String[] args2 = this.args;
for (int i = 0; i < args2.length; i++) {
String arg = args2[i];
String lowerCase = arg.toLowerCase(Locale.US);
if (lowerCase.equals(argToCheck2)) {
this.lastIndex = i;
return arg;
}
}
return null;
}
public String getNext() {
return this.args[this.lastIndex++];
}
@Override
public String toString() {
return Arrays.toString(this.args);
}
public String getMode() {
return this.args[0];
}
public String get(int i) {
return this.args[i];
}
}

View File

@ -0,0 +1,119 @@
/*
* Copyright 2012 dorkbox, llc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dorkbox.build.util;
import java.io.PrintStream;
import dorkbox.util.OS;
public class BuildLog {
private static boolean suppressOutput = false;
public static void start() {
suppressOutput = false;
}
public static void stop() {
suppressOutput = true;
}
private PrintStream printer;
private String title;
public BuildLog() {
this.printer = System.err;
}
public BuildLog(PrintStream printer) {
this.printer = printer;
}
public BuildLog title(String title) {
this.title = title;
return this;
}
public void message() {
message((String) null);
}
public void message(String... message) {
if (suppressOutput) {
return;
}
String spacer = " ";
if (this.title == null) {
this.title = spacer;
} else {
int length = this.title.length();
int padding = 16 - length;
if (padding > 0) {
StringBuilder msg = new StringBuilder(16);
msg.append(this.title);
for (int i = 0; i < padding; i++) {
msg.append(" ");
}
this.title = msg.toString();
}
}
if (message != null && message.length > 0 && message[0] != null) {
StringBuilder msg = new StringBuilder(1024);
int start = 0;
if (message.length > 1) {
msg.append(this.title).append(": ").append(message[start++]);
}
String newLineToken = OS.LINE_SEPARATOR;
for (int i = start; i < message.length; i++) {
String m = message[i];
if (msg.length() > 0) {
msg.append(newLineToken);
}
msg.append(spacer).append(": ").append(" ").append(m);
}
this.printer.println(msg.toString());
} else {
StringBuilder msg = new StringBuilder(1024);
msg.append(this.title).append(":");
this.printer.println(msg.toString());
}
}
public void print(String message) {
if (suppressOutput) {
return;
}
this.printer.print(message);
}
public void println(String message) {
if (suppressOutput) {
return;
}
this.printer.println(message);
}
public void write(int b) {
if (suppressOutput) {
return;
}
this.printer.write(b);
}
}

View File

@ -0,0 +1,124 @@
/*
* Copyright 2012 dorkbox, llc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dorkbox.build.util;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import com.esotericsoftware.wildcard.Paths;
import com.esotericsoftware.yamlbeans.YamlException;
import com.esotericsoftware.yamlbeans.YamlReader;
import com.esotericsoftware.yamlbeans.parser.Parser.ParserException;
import com.esotericsoftware.yamlbeans.tokenizer.Tokenizer.TokenizerException;
import dorkbox.build.SimpleArgs;
import dorkbox.util.FileUtil;
import dorkbox.util.Sys;
public class BuildParser {
public static String fileName = "build.oak";
@SuppressWarnings("unchecked")
public static HashMap<String, Object> parse(SimpleArgs args) {
String fileName = BuildParser.fileName;
if (args.has("-file") || args.has("-f")) {
fileName = args.getNext();
}
final File file = new File(FileUtil.normalizeAsFile(fileName));
HashMap<String, Object> data = null;
Reader fileReader = null;
try {
fileReader = new FileReader(file);
YamlReader yamlReader = new YamlReader(fileReader) {
@SuppressWarnings("rawtypes")
@Override
protected Object readValue (Class type, Class elementType, Class defaultType) throws YamlException, ParserException,
TokenizerException {
Object value = super.readValue(type, elementType, defaultType);
// replace $dir$ with the parent dir, for use in parameters
if (value instanceof String) {
value = ((String)value).replaceAll("\\$dir\\$", file.getParent());
}
return value;
}
};
try {
data = yamlReader.read(HashMap.class);
yamlReader.close();
if (data == null) {
return new HashMap<String, Object>(0);
} else {
return data;
}
} catch (YamlException ex) {
throw new IOException("Error reading YAML file: " + file, ex);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
Sys.close(fileReader);
}
return new HashMap<String, Object>(0);
}
public static Paths getPathsFromMap(HashMap<String, Object> map, String key) throws IOException {
Paths sourcePaths = new Paths();
if (map.containsKey(key)) {
Object object = map.get(key);
if (object instanceof String) {
sourcePaths.glob(".", (String) object);
} else if (object instanceof Collection) {
@SuppressWarnings("rawtypes")
Collection col = (Collection) object;
for (Object c : col) {
// we use the full path info
Paths paths = new Paths(".", (String) c);
if (paths.isEmpty()) {
throw new IOException("Location does not exist: " + c);
} else {
Iterator<String> iterator = paths.iterator();
while (iterator.hasNext()) {
String next = FileUtil.normalizeAsFile(iterator.next());
File file = new File(next);
if (!file.canRead()) {
throw new IOException("Location does not exist: " + next);
}
sourcePaths.add(file.getParent(), file.getName());
}
}
}
} else {
throw new IOException("Unknown source type: " + object.getClass().getSimpleName());
}
}
return sourcePaths;
}
}

View File

@ -0,0 +1,90 @@
/*
* Copyright 2012 dorkbox, llc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dorkbox.build.util;
import java.security.ProtectionDomain;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
public class ByteClassloader extends java.lang.ClassLoader {
private Map<String, byte[]> bytes = new ConcurrentHashMap<String, byte[]>();
private Map<String, Class<?>> classes = new ConcurrentHashMap<String, Class<?>>();
private final ProtectionDomain domain;
public ByteClassloader(ClassLoader classloader) {
super(classloader);
this.domain = this.getClass().getProtectionDomain();
}
public final void saveBytes(String name, byte[] bytes) {
// this defines our class, and saves it in our cache -- so that findClass() will work
if (this.bytes != null) {
this.bytes.put(name, bytes);
}
}
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
return loadClass(name, false);
}
// check OURSELVES first, then check our parent.
@Override
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
if (this.bytes != null) {
byte[] classBytes = this.bytes.get(name);
if (classBytes != null) {
// have to make sure that the package is properly setup.
int i = -1;
String packageName = name;
while ((i = name.indexOf('.', i)) > 0) {
packageName = name.substring(0, i++);
if (getPackage(packageName) == null) {
definePackage(packageName, null, null, null, null, null, null, null);
}
}
Class<?> clazz = defineClass(name, classBytes, 0, classBytes.length, this.domain);
if (resolve) {
resolveClass(clazz);
}
// cache our classes that we create
this.classes.put(name, clazz);
return clazz;
}
}
Class<?> c = this.classes.get(name);
if (c != null) {
return c;
}
return getParent().loadClass(name);
}
Iterator<Entry<String, byte[]>> getBytesIterator() {
return this.bytes.entrySet().iterator();
}
}

View File

@ -0,0 +1,106 @@
/*
* Copyright 2012 dorkbox, llc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dorkbox.build.util;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.Map.Entry;
import dorkbox.util.annotation.ClassFileIterator;
/**
* {@code ClassBytesIterator} is used to iterate over all Java ClassFile files available within
* a specific context.
* <p>
* For every Java ClassFile ({@code .class}) an {@link InputStream} is returned.
*/
public class ClassByteIterator extends ClassFileIterator {
private final Iterator<Entry<String, byte[]>> iterator;
private String fullPath;
/**
* Create a new {@code ClassFileIterator} returning all Java ClassFile files available
* from the specified files and/or directories, including sub directories.
* <p>
* If the (optional) package filter is defined, only class files staring with one of the
* defined package names are returned.
* NOTE: package names must be defined in the native format (using '/' instead of '.').
*/
public ClassByteIterator(final ByteClassloader classloader, final String[] pkgNameFilter) {
super(pkgNameFilter);
this.iterator = classloader.getBytesIterator();
}
/**
* Return the name of the Java ClassFile returned from the last call to {@link #next()}.
* The name is the PACKAGE name of a file
*/
@Override
public String getName() {
return this.fullPath;
}
/**
* Return {@code true} if the current {@link InputStream} is reading from a plain
* {@link File}.
* Return {@code false} if the current {@link InputStream} is reading from a
* ZIP File Entry.
*/
@Override
public boolean isFile() {
return true;
}
/**
* Return the next Java ClassFile as an {@code InputStream}.
* <p>
* NOTICE: Client code MUST close the returned {@code InputStream}!
*/
@Override
public InputStream next(final FilenameFilter filter) throws IOException {
while (this.iterator.hasNext()) {
Entry<String, byte[]> next = this.iterator.next();
this.fullPath = next.getKey();
File dir = null;
String name = null;
int lastIndexOf = this.fullPath.lastIndexOf(".");
if (filter != null) {
if (lastIndexOf > 0) {
dir = new File(this.fullPath.substring(0, lastIndexOf));
name = this.fullPath.substring(lastIndexOf+1);
}
} else {
name = this.fullPath;
}
if (filter == null || filter.accept(dir, name)) {
return new ByteArrayInputStream(next.getValue());
}
// else just ignore
}
return null;
}
}

View File

@ -0,0 +1,99 @@
/*
* Copyright 2012 dorkbox, llc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dorkbox.build.util;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
import java.util.HashMap;
import java.util.Map.Entry;
import javax.tools.FileObject;
import javax.tools.ForwardingJavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import com.esotericsoftware.wildcard.Paths;
public class JavaMemFileManager extends ForwardingJavaFileManager<StandardJavaFileManager> {
static class ClassMemFileObject extends SimpleJavaFileObject {
ByteArrayOutputStream os = new ByteArrayOutputStream();
ClassMemFileObject(String className) {
super(URI.create("mem:///" + className + Kind.CLASS.extension), Kind.CLASS);
}
byte[] getBytes() {
return this.os.toByteArray();
}
@Override
public OutputStream openOutputStream() throws IOException {
return this.os;
}
}
private HashMap<String, ClassMemFileObject> classes = new HashMap<String, ClassMemFileObject>();
private Paths source;
private ByteClassloader bytesClassloader;
public JavaMemFileManager(StandardJavaFileManager standardFileManager, ByteClassloader bytesClassloader) {
super(standardFileManager);
this.bytesClassloader = bytesClassloader;
}
@Override
public JavaFileObject getJavaFileForOutput(Location location, String className, JavaFileObject.Kind kind, FileObject sibling)
throws IOException {
if (StandardLocation.CLASS_OUTPUT == location && JavaFileObject.Kind.CLASS == kind) {
ClassMemFileObject clazz = new ClassMemFileObject(className);
this.classes.put(className, clazz);
return clazz;
} else {
return super.getJavaFileForOutput(location, className, kind, sibling);
}
}
public void setSource(Paths source) {
this.source = source;
}
public Iterable<? extends JavaFileObject> getSourceFiles() {
return super.fileManager.getJavaFileObjectsFromFiles(this.source.getFiles());
}
@Override
public void close() throws IOException {
super.close();
// and save all of our bytes into our classloader
for (Entry<String, ClassMemFileObject> entry : this.classes.entrySet()) {
String key = entry.getKey();
ClassMemFileObject value = entry.getValue();
this.bytesClassloader.saveBytes(key, value.getBytes());
}
this.classes.clear();
}
}

View File

@ -0,0 +1,20 @@
/*
* Copyright 2012 dorkbox, llc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dorkbox.build.util;
public interface PreJarAction {
public void executeBeforeJarHappens(String outputDir) throws Exception;
}

View File

@ -0,0 +1,24 @@
/*
* Copyright 2012 dorkbox, llc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dorkbox.build.util.jar;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
public interface EncryptInterface {
/** Specify how data is to be encrypted, if specified */
ByteArrayOutputStream encrypt(InputStream inputStream, int length);
}

View File

@ -0,0 +1,23 @@
/*
* Copyright 2012 dorkbox, llc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dorkbox.build.util.jar;
import java.util.zip.ZipEntry;
public interface ExtraDataInterface {
void write(ZipEntry entry, PackTask task);
}

View File

@ -0,0 +1,44 @@
/*
* Copyright 2012 dorkbox, llc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dorkbox.build.util.jar;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import com.esotericsoftware.wildcard.Paths;
import dorkbox.license.License;
public class JarOptions {
public String outputFile = null;
public Paths inputPaths = null;
public String mainClass = null;
public Map<String,String> otherManifestAttributes = new LinkedHashMap<String, String>();
public Paths classpath = null;
public boolean createDebugVersion = false;
/** target dir + paths for extra files **/
public Paths extraPaths;
/** Include the source code if requested **/
public Paths sourcePaths;
/** Include the various licenses if possible **/
public List<License> licenses;
}

View File

@ -0,0 +1,319 @@
/*
* Copyright 2012 dorkbox, llc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dorkbox.build.util.jar;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.MessageDigest;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.Map;
import java.util.Map.Entry;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1TaggedObject;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.cms.ContentInfo;
import org.bouncycastle.asn1.cms.SignedData;
import dorkbox.util.Base64Fast;
import dorkbox.util.OS;
import dorkbox.util.Sys;
public class JarSignatureUtil {
/**
* a small helper function that will convert a manifest into an array of
* bytes
*/
public static final byte[] serialiseManifest(Manifest manifest) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
manifest.write(baos);
baos.flush();
baos.close();
return baos.toByteArray();
}
/**
* update the attributes in the manifest to have the appropriate message
* digests. we store the new entries into the entries Map and return it (we
* do not compute the digests for those entries in the META-INF directory)
*/
public static final Map<String, Attributes> updateManifestHashes(Manifest manifest, JarFile jarFile, MessageDigest messageDigest) throws IOException {
Map<String, Attributes> entries = manifest.getEntries();
Enumeration<JarEntry> jarElements = jarFile.entries();
String digestName = messageDigest.getAlgorithm() + "-Digest";
while (jarElements.hasMoreElements()) {
JarEntry jarEntry = jarElements.nextElement();
String name = jarEntry.getName();
if (name.startsWith(JarUtil.metaInfName)) {
continue;
} else if (!jarEntry.isDirectory()) {
// store away the digest into a new Attribute
// because we don't already have an attribute list
// for this entry. we do not store attributes for
// directories within the JAR
Attributes attributes = new Attributes();
// attributes.putValue("Name", name); NOT NECESSARY!
InputStream inputStream = jarFile.getInputStream(jarEntry);
attributes.putValue(digestName, JarUtil.updateDigest(inputStream, messageDigest));
Sys.close(inputStream);
entries.put(name, attributes);
}
}
return entries;
}
/**
* @return null if there is a problem with the certificate loading process.
*/
public static final String extractSignatureHashFromSignatureBlock(byte[] signatureBlock) {
ASN1InputStream sigStream = null;
try {
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
InputStream signatureIn = new ByteArrayInputStream(signatureBlock);
sigStream = new ASN1InputStream(signatureIn);
ASN1Primitive signatureASN = sigStream.readObject();
ASN1Sequence seq = ASN1Sequence.getInstance(signatureASN);
ASN1TaggedObject tagged = (ASN1TaggedObject) seq.getObjectAt(1);
// Extract certificates
SignedData newSignedData = SignedData.getInstance(tagged.getObject());
@SuppressWarnings("rawtypes")
Enumeration newSigOjects = newSignedData.getCertificates().getObjects();
Object newSigElement = newSigOjects.nextElement();
if (newSigElement instanceof DERSequence) {
DERSequence newSigDERElement = (DERSequence) newSigElement;
InputStream newSigIn = new ByteArrayInputStream(newSigDERElement.getEncoded());
Certificate newSigCertificate = certFactory.generateCertificate(newSigIn);
// certificate bytes
byte[] newSigCertificateBytes = newSigCertificate.getEncoded();
String encodeToString = Base64Fast.encodeToString(newSigCertificateBytes, false);
return encodeToString;
}
} catch (IOException e) {} catch (CertificateException e) {}
finally {
Sys.close(sigStream);
}
return null;
}
/**
* Verify that the two certificates MATCH from within a signature block (ie,
* XXXXX.DSA in the META-INF directory).
*
* @return true if the two certificates are the same. false otherwise.
*/
public static final boolean compareCertificates(byte[] newSignatureContainerBytes, byte[] oldSignatureContainerBytes) {
ASN1InputStream newSigStream = null;
ASN1InputStream oldSigStream = null;
try {
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
InputStream newSignatureIn = new ByteArrayInputStream(newSignatureContainerBytes);
newSigStream = new ASN1InputStream(newSignatureIn);
ASN1Primitive newSigASNPrim = newSigStream.readObject();
ContentInfo newSigContent = ContentInfo.getInstance(newSigASNPrim);
InputStream oldSignatureIn = new ByteArrayInputStream(oldSignatureContainerBytes);
oldSigStream = new ASN1InputStream(oldSignatureIn);
ASN1Primitive oldSigASNPrim = oldSigStream.readObject();
ContentInfo oldSigContent = ContentInfo.getInstance(oldSigASNPrim);
// Extract certificates
SignedData newSignedData = SignedData.getInstance(newSigContent.getContent());
@SuppressWarnings("rawtypes")
Enumeration newSigOjects = newSignedData.getCertificates().getObjects();
SignedData oldSignedData = SignedData.getInstance(oldSigContent.getContent());
@SuppressWarnings("rawtypes")
Enumeration oldSigOjects = oldSignedData.getCertificates().getObjects();
Object newSigElement = newSigOjects.nextElement();
Object oldSigElement = oldSigOjects.nextElement();
if (newSigElement instanceof DERSequence && oldSigElement instanceof DERSequence) {
DERSequence newSigDERElement = (DERSequence) newSigElement;
InputStream newSigIn = new ByteArrayInputStream(newSigDERElement.getEncoded());
Certificate newSigCertificate = certFactory.generateCertificate(newSigIn);
DERSequence oldSigDERElement = (DERSequence) oldSigElement;
InputStream oldSigIn = new ByteArrayInputStream(oldSigDERElement.getEncoded());
Certificate oldSigCertificate = certFactory.generateCertificate(oldSigIn);
// certificate bytes
byte[] newSigCertificateBytes = newSigCertificate.getEncoded();
byte[] oldSigCertificateBytes = oldSigCertificate.getEncoded();
return Arrays.equals(newSigCertificateBytes, oldSigCertificateBytes);
}
} catch (IOException e) {} catch (CertificateException e) {}
finally {
Sys.close(newSigStream);
Sys.close(oldSigStream);
}
return false;
}
/**
* Creates a NEW signature file manifest based on the supplied message
* digest and manifest.
*/
@SuppressWarnings("deprecation")
public static final Manifest createSignatureFileManifest(MessageDigest messageDigest, Manifest manifest, byte[] manifestBytes) throws IOException, SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
String messageDigestTitle = messageDigest.getAlgorithm() + "-Digest";
// create the new manifest signature (.SF)
Manifest signatureManifest = new Manifest();
Attributes signatureMainAttributes = signatureManifest.getMainAttributes();
signatureMainAttributes.putValue(Attributes.Name.SIGNATURE_VERSION.toString(), "1.0");
String version = System.getProperty("java.version");
String javaVendor = System.getProperty("java.vendor");
signatureMainAttributes.putValue("Created-By", version + " (" + javaVendor + ")");
// SIGN THE WHOLE MANIFEST
messageDigest.reset();
messageDigest.update(manifestBytes, 0, manifestBytes.length);
/*
* Do not insert a default newline at the end of the output line, as
* java.util.jar does its own line management (see
* Manifest.make72Safe()). Inserting additional new lines will cause
* line-wrapping problems.
*/
String entireManifestHash = Base64Fast.encodeToString(messageDigest.digest(), false);
signatureMainAttributes.putValue(messageDigestTitle + "-Manifest", entireManifestHash);
// System.err.println("ENCODED ALL : " + entireManifestHash);
// //////////////////////////
// Instead of reverse engineering the BYTES, we'll just read the
// manifest again and encode on the fly.
// //////////////////////////
ByteArrayOutputStream manifestStream = new ByteArrayOutputStream();
Method writeMainMethod = Attributes.class.getDeclaredMethod("writeMain",
new Class<?>[] {DataOutputStream.class});
writeMainMethod.setAccessible(true);
// MAIN ATTRIBUTES
DataOutputStream dataOutputStream = new DataOutputStream(manifestStream);
// Write out the main attributes for the manifest
writeMainMethod.invoke(manifest.getMainAttributes(), dataOutputStream);
dataOutputStream.flush();
manifestStream.flush();
// HASH the contents of the main attributes (WHICH ARE ALWAYS FIRST!)
byte[] mainAttributesByteArray = manifestStream.toByteArray();
messageDigest.reset();
messageDigest.update(mainAttributesByteArray, 0, mainAttributesByteArray.length);
/*
* Do not insert a default newline at the end of the output line, as
* java.util.jar does its own line management (see
* Manifest.make72Safe()). Inserting additional new lines will cause
* line-wrapping problems.
*/
String mainAttribsManifestHash = Base64Fast.encodeToString(messageDigest.digest(), false);
if (mainAttribsManifestHash != null) {
signatureMainAttributes.putValue(messageDigestTitle + "-Manifest-Main-Attributes", mainAttribsManifestHash);
// System.err.println("ENCODED main: " + mainAttribsManifestHash);
} else {
throw new RuntimeException("Unable to create manifest-main-attribute signature");
}
// PER-ENTRY ATTRIBUTES
Method writeMethod = Attributes.class.getDeclaredMethod("write", new Class<?>[] {DataOutputStream.class});
writeMethod.setAccessible(true);
Method make72Method = Manifest.class.getDeclaredMethod("make72Safe", new Class<?>[] {StringBuffer.class});
make72Method.setAccessible(true);
Map<String, Attributes> entries = manifest.getEntries();
Map<String, Attributes> signatureEntries = signatureManifest.getEntries();
for (Entry<String, Attributes> e : entries.entrySet()) {
manifestStream.reset();
dataOutputStream = new DataOutputStream(manifestStream);
// has to be string buffer.
StringBuffer buffer = new StringBuffer("Name: ");
String entryName = e.getKey();
if (entryName != null) {
byte[] vb = entryName.getBytes(OS.UTF_8); // by doing this, the following new string
// will be safe (UTF-8) despite warnings
entryName = new String(vb, 0, 0, vb.length);
}
buffer.append(entryName);
buffer.append("\r\n"); // must be this because of stupid windows...
make72Method.invoke(null, buffer);
dataOutputStream.writeBytes(buffer.toString());
// Write out the attributes for the manifest
writeMethod.invoke(e.getValue(), dataOutputStream);
dataOutputStream.flush();
manifestStream.flush();
// HASH the contents of the attributes
byte[] attributesByteArray = manifestStream.toByteArray();
messageDigest.reset();
messageDigest.update(attributesByteArray, 0, attributesByteArray.length);
/*
* Do not insert a default newline at the end of the output line, as
* java.util.jar does its own line management (see
* Manifest.make72Safe()). Inserting additional new lines will cause
* line-wrapping problems.
*/
String entryHash = Base64Fast.encodeToString(messageDigest.digest(), false);
Attributes attribute = new Attributes();
attribute.putValue(messageDigestTitle, entryHash);
signatureEntries.put(entryName, attribute);
// System.err.println("ENCODED " + entryName + " : " + entryHash);
}
return signatureManifest;
}
}

View File

@ -0,0 +1,316 @@
/*
* Copyright 2012 dorkbox, llc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dorkbox.build.util.jar;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.math.BigInteger;
import java.security.GeneralSecurityException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.Security;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.DSAParameter;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.params.DSAKeyParameters;
import org.bouncycastle.crypto.params.DSAParameters;
import org.bouncycastle.crypto.params.DSAPrivateKeyParameters;
import org.bouncycastle.crypto.params.DSAPublicKeyParameters;
import org.bouncycastle.crypto.util.PrivateKeyFactory;
import org.bouncycastle.crypto.util.PublicKeyFactory;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import dorkbox.Build;
import dorkbox.util.Base64Fast;
import dorkbox.util.Sys;
import dorkbox.util.crypto.Crypto;
import dorkbox.util.crypto.CryptoX509;
public class JarSigner {
static {
BouncyCastleProvider provider = new BouncyCastleProvider();
Security.addProvider(provider);
}
public static File sign(String jarName, String name) {
Build.log().message();
Build.log().title("Signing JAR").message(jarName, name.toUpperCase());
if (jarName == null) {
throw new IllegalArgumentException("jarName cannot be null.");
}
try {
File jarFile = new File(jarName);
ByteArrayOutputStream signJarFile;
if (jarFile.isFile() && jarFile.canRead()) {
signJarFile = signJar(jarFile, name);
} else {
throw new RuntimeException("Unable to read file: " + jarFile.getCanonicalPath());
}
// write out the file
OutputStream outputStream = new FileOutputStream(jarFile);
signJarFile.writeTo(outputStream);
Sys.close(outputStream);
return new File(jarName);
}
catch (Throwable ex) {
throw new RuntimeException("Unable to sign jar file! " + ex.getMessage());
}
}
/**
* the actual JAR signing method
* @param createDebugVersion
*/
private static ByteArrayOutputStream signJar(File jarFile, String name)
throws IOException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, GeneralSecurityException {
// proper "jar signing" does not allow for ECC signatures to be used. RSA/DSA and that's it.
// so this "self signed" cert is just that. wimpy.
// the magic is in the uber-strong ECC key that is used internally, and also has AES keys mixed in.
DSAKeyParameters[] wimpyKeys = getWimpyKeys();
DSAPublicKeyParameters wimpyPublicKey = (DSAPublicKeyParameters) wimpyKeys[0];
DSAPrivateKeyParameters wimpyPrivateKey = (DSAPrivateKeyParameters) wimpyKeys[1];
// create the certificate
Calendar expiry = Calendar.getInstance();
expiry.add(Calendar.YEAR, 2);
Date startDate = new Date(); // time from which certificate is valid
Date expiryDate = expiry.getTime(); // time after which certificate is not valid
BigInteger serialNumber = BigInteger.valueOf(System.currentTimeMillis()); // serial number for certificate
X509CertificateHolder wimpyX509CertificateHolder = CryptoX509.DSA.createCertHolder(
startDate, expiryDate,
new X500Name("ST=Lunar Base Alpha, O=Dorkbox, CN=Dorkbox Server, emailaddress=admin@dorkbox.com"),
new X500Name("ST=Earth, O=Dorkbox, CN=Dorkbox Client, emailaddress=admin@dorkbox.com"),
serialNumber, wimpyPrivateKey, wimpyPublicKey);
JarFile jar = new JarFile(jarFile.getCanonicalPath());
// UNFORTUNATELY, with java6, we CANNOT do anything higher. As such, a CUSTOM signing tool will be developed,
// which the launcher will verify on it's own.
// FORTUNATELY, this is will produce the exact same output as if using the command line.
String digestName = CryptoX509.Util.getDigestNameFromCert(wimpyX509CertificateHolder);
MessageDigest messageDigest = MessageDigest.getInstance(digestName);
// get the manifest out of the jar.
Manifest manifest = JarUtil.getManifestFile(jar);
// it ONLY exists if it's an "executable" jar
if (manifest == null) {
manifest = new Manifest();
// have to add basic entries.
Attributes mainAttributes = manifest.getMainAttributes();
mainAttributes.putValue(Attributes.Name.MANIFEST_VERSION.toString(), "1.0");
} else {
// clear out all entries in the manifest
Map<String, Attributes> entries = manifest.getEntries();
if (entries.size() > 0) {
entries.clear();
}
}
// create the message digest and start updating the
// the attributes in the manifest to contain the SHA digests
JarSignatureUtil.updateManifestHashes(manifest, jar, messageDigest);
byte manifestBytes[] = JarSignatureUtil.serialiseManifest(manifest);
// create a NEW signature file manifest based on the supplied message digest and manifest.
Manifest signatureFileManifest = JarSignatureUtil.createSignatureFileManifest(messageDigest, manifest, manifestBytes);
byte signatureFileManifestBytes[] = JarSignatureUtil.serialiseManifest(signatureFileManifest);
byte signatureBlockBytes[] = CryptoX509.createSignature(signatureFileManifestBytes,
wimpyX509CertificateHolder, wimpyPrivateKey);
ByteArrayOutputStream byteArrayOutputStream = JarUtil.createNewJar(jar,
name,
manifestBytes,
signatureFileManifestBytes,
signatureBlockBytes);
// close the JAR file that we have been using
jar.close();
return byteArrayOutputStream;
}
public static DSAKeyParameters[] getWimpyKeys() throws IOException, FileNotFoundException {
String wimpyKeyName = "wimpyCert.key";
DSAPrivateKeyParameters wimpyPrivateKey = null;
DSAPublicKeyParameters wimpyPublicKey = null;
File wimpyKeyRawFile = new File(wimpyKeyName);
// do we need to create the (wimpy) certificate keys?
if (!wimpyKeyRawFile.canRead()) {
// using DSA, since that is compatible with ALL java versions
@SuppressWarnings("deprecation")
AsymmetricCipherKeyPair generateKeyPair = Crypto.DSA.generateKeyPair(new SecureRandom(), 8192);
wimpyPrivateKey = (DSAPrivateKeyParameters) generateKeyPair.getPrivate();
wimpyPublicKey = (DSAPublicKeyParameters) generateKeyPair.getPublic();
writeDsaKeysToFile(wimpyPrivateKey, wimpyPublicKey, wimpyKeyRawFile);
} else {
FileInputStream inputStream = new FileInputStream(wimpyKeyRawFile);
long fileSize = inputStream.getChannel().size();
// check file size.
if (fileSize > Integer.MAX_VALUE-1) {
System.err.println("Corrupt wimpyKeyFile! " + wimpyKeyRawFile.getAbsolutePath() + " Creating a new one.");
// using DSA, since that is compatible with ALL java versions
@SuppressWarnings("deprecation")
AsymmetricCipherKeyPair generateKeyPair = Crypto.DSA.generateKeyPair(new SecureRandom(), 8192);
wimpyPrivateKey = (DSAPrivateKeyParameters) generateKeyPair.getPrivate();
wimpyPublicKey = (DSAPublicKeyParameters) generateKeyPair.getPublic();
writeDsaKeysToFile(wimpyPrivateKey, wimpyPublicKey, wimpyKeyRawFile);
} else {
// read in the entire file as bytes.
int fileSizeAsInt = (int) fileSize;
byte[] inputBytes = new byte[fileSizeAsInt];
inputStream.read(inputBytes, 0, fileSizeAsInt);
Sys.close(inputStream);
// read public key length
int wimpyPublicKeyLength = (inputBytes[fileSizeAsInt - 4] & 0xff) << 24 |
(inputBytes[fileSizeAsInt - 3] & 0xff) << 16 |
(inputBytes[fileSizeAsInt - 2] & 0xff) << 8 |
(inputBytes[fileSizeAsInt - 1] & 0xff) << 0;
byte[] publicKeyBytes = new byte[wimpyPublicKeyLength];
byte[] privateKeyBytes = new byte[fileSizeAsInt - 4 - wimpyPublicKeyLength];
System.arraycopy(inputBytes, 0, publicKeyBytes, 0, publicKeyBytes.length);
System.arraycopy(inputBytes, publicKeyBytes.length, privateKeyBytes, 0, privateKeyBytes.length);
displayByteHash(publicKeyBytes);
wimpyPublicKey = (DSAPublicKeyParameters) PublicKeyFactory.createKey(publicKeyBytes);
wimpyPrivateKey = (DSAPrivateKeyParameters) PrivateKeyFactory.createKey(privateKeyBytes);
}
}
return new DSAKeyParameters[] {wimpyPublicKey, wimpyPrivateKey};
}
private static void writeDsaKeysToFile(DSAPrivateKeyParameters wimpyPrivateKey, DSAPublicKeyParameters wimpyPublicKey, File wimpyKeyRawFile)
throws IOException, FileNotFoundException {
DSAParameters parameters = wimpyPublicKey.getParameters(); // has to convert to DSAParameter so encoding works.
byte[] publicKeyBytes = new SubjectPublicKeyInfo(
new AlgorithmIdentifier(X9ObjectIdentifiers.id_dsa,
new DSAParameter(parameters.getP(), parameters.getQ(), parameters.getG()).toASN1Primitive()),
new ASN1Integer(wimpyPublicKey.getY())).getEncoded();
// SAME AS:
// Certificate[] certificates = Launcher.class.getProtectionDomain().getCodeSource().getCertificates();
// if (certificates.length != 1) {
// // WHOOPS!
// Exit.FailedSecurity("Incorrect certificate length!");
// }
//
// Certificate certificate = certificates[0];
// PublicKey publicKey = certificate.getPublicKey();
// byte[] publicKeyBytes = publicKey.getEncoded();
//
// digest.reset();
// digest.update(publicKeyBytes, 0, publicKeyBytes.length);
// hashPublicKeyBytes = digest.digest();
parameters = wimpyPrivateKey.getParameters();
byte[] privateKeyBytes = new PrivateKeyInfo(
new AlgorithmIdentifier(X9ObjectIdentifiers.id_dsa,
new DSAParameter(parameters.getP(), parameters.getQ(), parameters.getG()).toASN1Primitive()),
new ASN1Integer(wimpyPrivateKey.getX())).getEncoded();
// write public length to bytes.
byte[] publicKeySize = new byte[] {(byte) (publicKeyBytes.length >>> 24),
(byte) (publicKeyBytes.length >>> 16),
(byte) (publicKeyBytes.length >>> 8),
(byte) (publicKeyBytes.length >>> 0)};
ByteArrayOutputStream keyOutputStream = new ByteArrayOutputStream(4 + publicKeyBytes.length + privateKeyBytes.length);
keyOutputStream.write(publicKeyBytes, 0, publicKeyBytes.length);
keyOutputStream.write(privateKeyBytes, 0, privateKeyBytes.length);
keyOutputStream.write(publicKeySize, 0, publicKeySize.length); // mess with people staring at the keys (store length at the end).
displayByteHash(publicKeyBytes);
// write out the file
OutputStream outputStream = new FileOutputStream(wimpyKeyRawFile);
keyOutputStream.writeTo(outputStream);
Sys.close(outputStream);
}
private static void displayByteHash(byte[] publicKeyBytes) {
try {
MessageDigest digest = MessageDigest.getInstance("SHA-512");
digest.reset();
digest.update(publicKeyBytes, 0, publicKeyBytes.length);
String digestString = Base64Fast.encodeToString(digest.digest(), false);
String origDigestHash = "9f5LkG90ITAMR37xxbXGXAGyaGkZL1dP7FzU8y/CL8gskIxegZTRbOn0g3ks/eCJ5jSKTX4eVZCPmA0TKj7zlw==";
if (!digestString.equals(origDigestHash)) {
System.err.println("Wimpy public key bytes. Need to modify " + JarSigner.class.getSimpleName() + " and in the Launcher");
System.err.println(digestString);
}
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,34 @@
/*
* Copyright 2012 dorkbox, llc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dorkbox.build.util.jar;
public class Pack extends Repack {
private final String destPath;
public Pack(String sourcePath, String destPath, PackAction... actions) {
super(sourcePath, actions);
this.destPath = destPath;
}
public String getSourcePath() {
return getName();
}
public String getDestPath() {
return this.destPath;
}
}

View File

@ -0,0 +1,488 @@
/*
* Copyright 2012 dorkbox, llc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dorkbox.build.util.jar;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.RandomAccessFile;
import java.util.HashMap;
import java.util.Map;
import java.util.jar.JarInputStream;
import java.util.jar.JarOutputStream;
import java.util.jar.Pack200;
import java.util.jar.Pack200.Packer;
import java.util.jar.Pack200.Unpacker;
import dorkbox.util.OS;
import dorkbox.util.Sys;
// OBSERVATION for JAR normalization
// java-pack/unpack and command-line pack/unpack produce DIFFERENT results.
// java-pack != CL-pack
// java-unpack != CL-unpack
// java-pack + java-unpack != java-pack + CL-unpack
//
// java-pack + CL-unpack = java-pack + CL-unpack
// java-pack + java+unpack + CL-pack + CL-unpack = java-pack + CL-unpack
public class Pack200Util {
private static String javaBinLocation;
public static byte[] PACK200_HEADER = { -54, -2, -48, 13 };
public static final Map<String, String> packOptions = new HashMap<String, String>(3);
static {
// have to make sure to use the "unpack200" associated with the java binary that is running.
Map<String, String> systemProperties = java.lang.management.ManagementFactory.getRuntimeMXBean().getSystemProperties();
javaBinLocation = systemProperties.get("java.home") + File.separatorChar + "bin";
// from http://stackoverflow.com/questions/3312401/how-to-make-an-ant-task-to-sign-and-pack200-all-my-jar-files
// these are the REQUIRED OPTIONS in order to make BOUNCYCASTLE jar verification PASS.
// The HASH on the file will be different than the ORIGINAL hash. The "unpacked" hash will remain constant between pack/unpack cycles
packOptions.put(Packer.MODIFICATION_TIME, Packer.KEEP);
// keep whatever sort of jar compression was originally used
packOptions.put(Packer.DEFLATE_HINT, Packer.KEEP);
// use largest-possible archive segments (>10% better compression).
packOptions.put(Packer.SEGMENT_LIMIT, "-1");
}
/**
* @return true if the file is a pack200 file
*/
public static boolean isPack200File(File file) {
boolean isZip = true;
byte[] buffer = new byte[PACK200_HEADER.length];
RandomAccessFile raf = null;
try {
raf = new RandomAccessFile(file, "r");
raf.readFully(buffer);
for (int i = 0; i < PACK200_HEADER.length; i++) {
if (buffer[i] != PACK200_HEADER[i]) {
isZip = false;
break;
}
}
} catch (Exception e) {
isZip = false;
} finally {
if (raf != null) {
try {
raf.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return isZip;
}
/**
* @return true if the file is a pack200 stream
*/
public static boolean isPack200Stream(ByteArrayInputStream input) {
boolean isZip = true;
int length = PACK200_HEADER.length;
try {
input.mark(length+1);
for (int i = 0; i < length; i++) {
byte read = (byte) input.read();
if (read != PACK200_HEADER[i]) {
isZip = false;
break;
}
}
input.reset();
} catch (Exception e) {
isZip = false;
}
return isZip;
}
/**
* @param inputStream
* @return true if the file can (or rather should) be packed.
*/
public static boolean canPack200(Repack repack, InputStream inputStream ) {
if (repack.canDo(PackAction.Pack)) {
String extension = repack.getExtension();
if (inputStream instanceof ByteArrayInputStream) {
// only pack200 certain files.
if (JarUtil.isZipStream((ByteArrayInputStream)inputStream)) {
return true;
}
} else if (".jar".equals(extension) || ".war".equals(extension) || ".ear".equals(extension) || ".ejb".equals(extension)) {
File file = new File(repack.getName());
// only pack200 certain files.
if (JarUtil.isZipFile(file)) {
return true;
}
}
}
return false;
}
public static class CommandLine {
public static ByteArrayOutputStream pack200(InputStream inputStream) throws IOException {
File source = File.createTempFile("temp", ".jar").getAbsoluteFile();
File dest = File.createTempFile("temp", ".pack").getAbsoluteFile();
source.delete();
dest.delete();
FileOutputStream fileOutputStream = new FileOutputStream(source);
Sys.copyStream(inputStream, fileOutputStream);
fileOutputStream.close();
String unpackName = "pack200";
if (OS.isWindows()) {
unpackName += ".exe";
}
commandLine(javaBinLocation + File.separatorChar + unpackName, "--no-gzip", "--segment-limit=-1", "--effort=1",
dest.getAbsolutePath(), source.getAbsolutePath());
FileInputStream fileInputStream = new FileInputStream(dest);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(fileInputStream.available());
Sys.copyStream(fileInputStream, outputStream);
source.delete();
dest.delete();
return outputStream;
}
public static ByteArrayOutputStream unpack200(InputStream inputStream) throws IOException {
File source = File.createTempFile("temp", ".pack").getAbsoluteFile();
File dest = File.createTempFile("temp", ".jar").getAbsoluteFile();
source.delete();
dest.delete();
FileOutputStream fileOutputStream = new FileOutputStream(source);
Sys.copyStream(inputStream, fileOutputStream);
fileOutputStream.close();
String unpackName = "unpack200";
if (OS.isWindows()) {
unpackName += ".exe";
}
commandLine(javaBinLocation + File.separatorChar + unpackName, source.getAbsolutePath(), dest.getAbsolutePath());
FileInputStream fileInputStream = new FileInputStream(dest);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(fileInputStream.available());
Sys.copyStream(fileInputStream, outputStream);
source.delete();
dest.delete();
return outputStream;
}
// run a command line, and wait for it to finish. There is no parsing the OUTPUT, so one must be EXTREMELY careful
// that the output isn't spammy.
private static void commandLine(String... command) {
try {
Process start = new ProcessBuilder(command).start();
while (true) {
try {
// throws an exception if the process hasn't exited yet.
start.exitValue();
// if we get here, we know the process finished.
break;
} catch (Exception e) {
try {
Thread.sleep(200);
} catch (InterruptedException e1) {
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static class Java {
/**
* SAFELY pack200 an input stream. There is an un-reported bug (java 6 is discontinued, so blah) concerning JarInputStream and
* reading the manifest during the Pack200 process. The problem is that the manifest, during a read/write cycle will CHANGE THE
* ORDER of the entries of the manifest. This is HORRID, since with jars that are SIGNED, it is CRITICAL that the manifest
* remains UNCHANGED.
*
* What this does, is read out the manifest, as a byte array, then when it's requested by the Pack200 process, it writes it
* back as the byte array --- skipping the parse/write cycle which mangles the order of the entries.
*
* NOTE: This version WILL BREAK jar signatures!
*
* @return a new ByteArrayOutputStream that contains the packed data.
*/
public static ByteArrayOutputStream pack200(InputStream inputStream, boolean addDebug) throws IOException {
// the problem is that the manifest RE-WRITES the bytes. verification of the RE-PACKED jar fails
// because the manifest bytes are different. Here, we want to DUPLICATE the bytes. By hook or by crook.
if (!(inputStream instanceof ByteArrayInputStream)) {
ByteArrayOutputStream baos = new ByteArrayOutputStream(inputStream.available());
Sys.copyStream(inputStream, baos);
Sys.close(inputStream);
inputStream = new ByteArrayInputStream(baos.toByteArray());
}
JarInputStream jarInputStream = SafeJarInputStream.create((ByteArrayInputStream)inputStream);
// Create the Packer object
Packer packer = Pack200.newPacker();
// Initialize the state by setting the desired properties
Map<String, String> p = packer.properties();
p.putAll(packOptions);
// reorder files for better compression.
// THIS WILL BREAK JAR SIGNATURES!
p.put(Packer.KEEP_FILE_ORDER, Packer.FALSE);
// extra options that are not required
p.put(Packer.EFFORT, "9"); // default is "5"
if (!addDebug) {
// discard debug attributes
p.put(Packer.CODE_ATTRIBUTE_PFX + "LineNumberTable", Packer.STRIP);
p.put(Packer.CODE_ATTRIBUTE_PFX + "SourceFile", Packer.STRIP);
p.put(Packer.CODE_ATTRIBUTE_PFX + "LocalVariableTable", Packer.STRIP);
p.put(Packer.CODE_ATTRIBUTE_PFX + "LocalVariableTypeTable", Packer.STRIP);
}
// we want to pack to a byte stream, which we will THEN compress, THEN encrypt!
ByteArrayOutputStream outputPackStream = new ByteArrayOutputStream(8096); // approx guess.
// stupid Pack200 warnings. This should do the trick...
PrintStream error = System.err;
System.setErr(new PrintStream(new OutputStream() {
@Override
public void write(int b) throws IOException {
// do NOTHING.
}
}));
// Call the packer
packer.pack(jarInputStream, outputPackStream);
System.setErr(error);
outputPackStream.flush();
Sys.close(outputPackStream);
Sys.close(jarInputStream);
return outputPackStream;
}
/**
* SAFELY pack200 an input stream. There is an un-reported bug (java 6 is discontinued, so blah) concerning JarInputStream and
* reading the manifest during the Pack200 process. The problem is that the manifest, during a read/write cycle will CHANGE THE
* ORDER of the entries of the manifest. This is HORRID, since with jars that are SIGNED, it is CRITICAL that the manifest
* remains UNCHANGED.
*
* What this does, is read out the manifest, as a byte array, then when it's requested by the Pack200 process, it writes it
* back as the byte array --- skipping the parse/write cycle which mangles the order of the entries.
*
* @return a new ByteArrayOutputStream that contains the packed data.
*/
public static ByteArrayOutputStream pack200_Default(InputStream inputStream) throws IOException {
// the problem is that the manifest RE-WRITES the bytes. verification of the RE-PACKED jar fails
// because the manifest bytes are different. Here, we want to DUPLICATE the bytes. By hook or by crook.
if (!(inputStream instanceof ByteArrayInputStream)) {
ByteArrayOutputStream baos = new ByteArrayOutputStream(inputStream.available());
Sys.copyStream(inputStream, baos);
Sys.close(inputStream);
inputStream = new ByteArrayInputStream(baos.toByteArray());
}
JarInputStream jarInputStream = SafeJarInputStream.create((ByteArrayInputStream)inputStream);
// Create the Packer object
Packer packer = Pack200.newPacker();
// Initialize the state by setting the desired properties
Map<String, String> p = packer.properties();
// use largest-possible archive segments (>10% better compression).
p.put(Packer.MODIFICATION_TIME, Packer.KEEP);
// keep whatever sort of jar compression was originally used
p.put(Packer.DEFLATE_HINT, Packer.KEEP);
// use largest-possible archive segments (>10% better compression).
p.put(Packer.SEGMENT_LIMIT, "-1");
p.put(Packer.EFFORT, "1");
// we want to pack to a byte stream, which we will THEN compress, THEN encrypt!
ByteArrayOutputStream outputPackStream = new ByteArrayOutputStream(8096); // approx guess.
// stupid Pack200 warnings. This should do the trick...
PrintStream error = System.err;
System.setErr(new PrintStream(new OutputStream() {
@Override
public void write(int b) throws IOException {
// do NOTHING.
}
}));
// Call the packer
packer.pack(jarInputStream, outputPackStream);
System.setErr(error);
Sys.close(jarInputStream);
outputPackStream.flush();
Sys.close(outputPackStream);
return outputPackStream;
}
/**
* Safely and properly UnPack200 a jar file - the RESULTANT jar will be DEFAULT COMPRESSION LEVEL
*
*
* Because we verify these files using the COMMAND LINE version of unpack200, which
* creates DIFFERENT files than calling unpack200 in java. Because we are hashing these files
* in their UNpacked state, we have to guarantee they are the same.
*
* In order to do so, we must ALSO use the commandline version of unpack200. This is
* very unfortunate, but alas it is necessary. There is no other way around this... I've tried many.
*
* See the implementation in the Jar UltraSigner on how I did it.
*/
public static ByteArrayOutputStream unpack200(ByteArrayInputStream inputStream) throws IOException {
// check to make sure that WE ARE INDEED a PACK200 archive!
if (!isPack200Stream(inputStream)) {
ByteArrayOutputStream baos = new ByteArrayOutputStream(inputStream.available());
Sys.copyStream(inputStream, baos);
Sys.close(inputStream);
return baos;
}
ByteArrayOutputStream unpackOutputStream = new ByteArrayOutputStream(8192);
JarOutputStream unpackJarOutputStream = new JarOutputStream(unpackOutputStream);
// stupid Pack200 warnings. This should do the trick...
PrintStream error = System.err;
System.setErr(new PrintStream(new OutputStream() {
@Override
public void write(int b) throws IOException {
// do NOTHING.
}
}));
// Call the unpacker
Unpacker unpacker = Pack200.newUnpacker();
// Initialize the state by setting the desired properties
Map<String, String> p = unpacker.properties();
// use largest-possible archive segments (>10% better compression).
// also required for repacking to work!
p.put(Packer.SEGMENT_LIMIT, "-1");
unpacker.unpack(inputStream, unpackJarOutputStream); // auto-closes the INPUT stream!
System.setErr(error);
Sys.close(inputStream); // Must explicitly close the input.
unpackJarOutputStream.flush();
unpackJarOutputStream.finish();
Sys.close(unpackJarOutputStream); // closing the stream ALSO adds meta-data to the output!
return unpackOutputStream;
}
/**
* Repack (or NORMALIZE) a jar with pack200. The file size will increase SLIGHTLY, however, it will be consistent with
* future pack200 operations.
* <p>
* The file will be left in an UNPACKED state.
*/
public static ByteArrayOutputStream repackJar(String filePath) throws IOException {
ByteArrayInputStream inputStream = new ByteArrayInputStream(Sys.getBytesFromStream(new FileInputStream(new File(filePath))));
return repackJar(inputStream);
}
/**
* Repack (or NORMALIZE) a jar with pack200. The filesize will increase SLIGHTLY, however, it will be consistent with
* future pack200 operations.
* <p>
* The file will be left in an UNPACKED state.
*/
public static ByteArrayOutputStream repackJar(File file) throws IOException {
ByteArrayInputStream inputStream = new ByteArrayInputStream(Sys.getBytesFromStream(new FileInputStream(file)));
return repackJar(inputStream);
}
/**
* Repack (or NORMALIZE) a jar with pack200. The filesize will increase SLIGHTLY, however, it will be consistent with
* future pack200 operations.
* <p>
* The file will be left in an UNPACKED state.
*/
public static ByteArrayOutputStream repackJar(InputStream inputStream) throws IOException {
// always make a copy, because pack200 closes the input stream!
ByteArrayOutputStream baos = new ByteArrayOutputStream(inputStream.available());
Sys.copyStream(inputStream, baos);
inputStream = new ByteArrayInputStream(baos.toByteArray());
ByteArrayOutputStream outputStream;
// make sure we are unpacked to begin with.
if (isPack200Stream((ByteArrayInputStream)inputStream)) {
outputStream = unpack200((ByteArrayInputStream)inputStream);
inputStream = new ByteArrayInputStream(outputStream.toByteArray());
}
outputStream = pack200_Default(inputStream);
// we want to UNPACK the jar now so we can get a proper file "packed" state
ByteArrayInputStream inputStream2 = new ByteArrayInputStream(outputStream.toByteArray());
outputStream = unpack200(inputStream2);
return outputStream;
}
}
}

View File

@ -0,0 +1,104 @@
/*
* Copyright 2012 dorkbox, llc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dorkbox.build.util.jar;
public enum PackAction {
// NOTE: these are packed into a TWO BYTES (for a total of 16 bitfields)
// if you add/change this, MAKE SURE you also check in Launcher and Bootstrap!!
// search for '// From PackAction' in all files to find the instances used!
//
// ALSO: the LGPL bit is 0, which means - NOTHING IS IN THE EXTRA DATA FIELD!
// By default, everything will be pack200+compressed
Store (1 << 31), // MAX_INT just store this file. Nothing will be done to it.
Extract (1 << 30), // MAX_INT/2 extract the contents of this compressed file to the root of the 'box' file (this is at compile time)
// The following affect the file load action
Pack (1 << 0), // 1 pack200 - everything (jar, etc) that can be pack200, IS pack200. We can detect this, so no
Lzma (1 << 1), // 2 we only use LZMA, since it offers better compression than gzip
Encrypt (1 << 2), // 4 aes encryption
/**
* means we want to load our classloader DIRECTLY via JNI, so we can set our classloader up before anything else
* WARNING. The files load in the order they are put in the jar - currently lexically, in alphabetical order. This matters a lot.
*/
ClassLoader (1 << 3, Pack.getValue() | Lzma.getValue()), // 8
/**
* means we want to load this into our classloader before our launcher is started.
*/
Load(1 << 4, Pack.getValue() | Lzma.getValue()), // 16
/**
* Load native libraries, or load jar's that are incompatible with our box file.
* <p>
* There's a comment that is the hash and pack+LZMA
* <p>
* It's not always possible to load our OWN libraries dll's, since some Java libraries have their
* own method to loading dll's.
* <p>
* we RELY on the the jar ALREADY being NORMALIZED (PACK+UNPACK) - if it's not, hashes won't match
*/
LoadLibray(1 << 5, Pack.getValue() | Lzma.getValue()), // 32
/**
* This is necessary for LGPL content. It will NOT be a part of the signature hash, and will NOT BE ENCRYPTED when using this.
* Resources/Javascript can also be LGPL (or variants).
* <p>
* This DOES NOT MEAN that the entire jar file/resource that is tagged LGPL is LGPL, just that part of it is.
* <p>
* Even if encrypt is "enabled" on an LGPL resource, the package process will IGNORE IT, since encrypt is not compatible with the
* LGPL license. It also means that this file can be REPLACED in the box container, since that is also part of the LGPL requirement
* so it is not hashed when ultra-signing the box containers!
*/
LGPL (1 << 6, Pack.getValue() | Lzma.getValue()), // 64
/**
* This means that files will be loaded by the bootstrap launcher. IF THIS ISN'T THERE, THEY WILL NOT BE LOADED!!
*/
Package(1 << 7, Pack.getValue() | Lzma.getValue() | Encrypt.getValue()), // 128
;
private final int value;
private final int baseValue;
private PackAction(int baseValue) {
this.value = baseValue;
this.baseValue = baseValue;
}
/**
* @param baseValue this is what the base value is for this pack action
* @param extraActions these are extra actions to perform in addition to whatever the "base value" action is.
*/
private PackAction(int baseValue, int extraActions) {
this.baseValue = baseValue;
this.value = baseValue | extraActions;
}
public int getBaseValue() {
return this.baseValue;
}
int getValue() {
return this.value;
}
}

View File

@ -0,0 +1,50 @@
/*
* Copyright 2012 dorkbox, llc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dorkbox.build.util.jar;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
public class PackTask {
InputStream inputStream;
public Repack pack;
long time;
int length;
boolean debug = false;
public byte[] extraData;
// info on signing the jar, if it's going to be encrypted.
EncryptInterface encryption;
public PackTask(Repack pack, byte[] entryAsBytes) {
this.pack = pack;
this.inputStream = new ByteArrayInputStream(entryAsBytes);
this.length = entryAsBytes.length;
}
public PackTask(Pack pack, InputStream inputStream) {
this.pack = pack;
this.inputStream = inputStream;
// length = inputStream.available(); // set in the calling method
}
@Override
public String toString() {
return "PackTask [" + this.pack.getName() + "]";
}
}

View File

@ -0,0 +1,104 @@
/*
* Copyright 2012 dorkbox, llc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dorkbox.build.util.jar;
public class Repack {
private final String name;
private int actionValue = 0;
public Repack(String name, PackAction... actions) {
this.name = name;
for (PackAction action : actions) {
this.actionValue |= action.getValue();
}
}
/**
* Remove an action, if it exists.
*/
public void remove(PackAction... actions) {
for (PackAction action : actions) {
if (canDo(action)) {
// undo the action.
this.actionValue ^= action.getValue();
}
}
}
public String getName() {
return this.name;
}
public boolean canDo(PackAction actionType) {
return (this.actionValue & actionType.getBaseValue()) == actionType.getBaseValue();
}
public int getAction() {
return this.actionValue;
}
public String getExtension() {
int extensionIndex = this.name.lastIndexOf('.');
if (extensionIndex > 0) {
return this.name.substring(extensionIndex).toLowerCase();
} else {
return "";
}
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + this.actionValue;
result = prime * result + (this.name == null ? 0 : this.name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Repack other = (Repack) obj;
if (this.actionValue != other.actionValue) {
return false;
}
if (this.name == null) {
if (other.name != null) {
return false;
}
} else if (!this.name.equals(other.name)) {
return false;
}
return true;
}
@Override
public String toString() {
return this.name;
}
}

View File

@ -0,0 +1,76 @@
/*
* Copyright 2012 dorkbox, llc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dorkbox.build.util.jar;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.jar.JarFile;
import java.util.jar.JarInputStream;
import java.util.jar.Manifest;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import dorkbox.util.Sys;
/**
* Necessary for preventing the manifest from mangling the order of it's contents.
*/
public class SafeJarInputStream extends JarInputStream {
private final byte[] manifestBytes;
public static SafeJarInputStream create(ByteArrayInputStream inputStream) throws IOException {
// we KNOW that the manifest is the FIRST zip entry!
// This is stupid, but the only way i know how to get the first entry
// ALSO.. might not have a manifest!
final byte[] manifestBytes;
ZipInputStream zipInputStream = new ZipInputStream(inputStream);
// this is the SAME as what a JarInputStream does, however the difference is
// that here we SAVE OUT the bytes, instead of parse them.
ZipEntry e = zipInputStream.getNextEntry();
if (e != null && e.getName().equalsIgnoreCase("META-INF/")) {
e = zipInputStream.getNextEntry();
}
if (e != null && JarFile.MANIFEST_NAME.equalsIgnoreCase(e.getName())) {
manifestBytes = Sys.getBytesFromStream(zipInputStream);
} else {
manifestBytes = null;
}
Sys.close(zipInputStream);
inputStream.reset();
return new SafeJarInputStream(inputStream, true, manifestBytes);
}
private SafeJarInputStream(InputStream in, boolean verify, byte[] manifestBytes) throws IOException {
super(in, verify);
this.manifestBytes = manifestBytes;
}
@Override
public Manifest getManifest() {
if (this.manifestBytes == null) {
return null;
}
return new SafeManifest(this.manifestBytes);
}
}

View File

@ -0,0 +1,42 @@
/*
* Copyright 2012 dorkbox, llc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dorkbox.build.util.jar;
import java.io.IOException;
import java.io.OutputStream;
import java.util.jar.Manifest;
/**
* Necessary for preventing the manifest from mangling the order of it's contents.
*/
public class SafeManifest extends Manifest {
private final byte[] manifestBytes;
SafeManifest(byte[] manifestBytes) {
this.manifestBytes = manifestBytes;
}
@Override
public void write(OutputStream out) throws IOException {
if (this.manifestBytes != null) {
out.write(this.manifestBytes, 0, this.manifestBytes.length);
}
}
public byte[] getBytes() {
return this.manifestBytes;
}
}

View File

@ -0,0 +1,218 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1,26 @@
BSD License
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the <ORGANIZATION> 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 TINKERPOP 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.

View File

@ -0,0 +1,121 @@
Creative Commons Legal Code
CC0 1.0 Universal
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
HEREUNDER.
Statement of Purpose
The laws of most jurisdictions throughout the world automatically confer
exclusive Copyright and Related Rights (defined below) upon the creator
and subsequent owner(s) (each and all, an "owner") of an original work of
authorship and/or a database (each, a "Work").
Certain owners wish to permanently relinquish those rights to a Work for
the purpose of contributing to a commons of creative, cultural and
scientific works ("Commons") that the public can reliably and without fear
of later claims of infringement build upon, modify, incorporate in other
works, reuse and redistribute as freely as possible in any form whatsoever
and for any purposes, including without limitation commercial purposes.
These owners may contribute to the Commons to promote the ideal of a free
culture and the further production of creative, cultural and scientific
works, or to gain reputation or greater distribution for their Work in
part through the use and efforts of others.
For these and/or other purposes and motivations, and without any
expectation of additional consideration or compensation, the person
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
is an owner of Copyright and Related Rights in the Work, voluntarily
elects to apply CC0 to the Work and publicly distribute the Work under its
terms, with knowledge of his or her Copyright and Related Rights in the
Work and the meaning and intended legal effect of CC0 on those rights.
1. Copyright and Related Rights. A Work made available under CC0 may be
protected by copyright and related or neighboring rights ("Copyright and
Related Rights"). Copyright and Related Rights include, but are not
limited to, the following:
i. the right to reproduce, adapt, distribute, perform, display,
communicate, and translate a Work;
ii. moral rights retained by the original author(s) and/or performer(s);
iii. publicity and privacy rights pertaining to a person's image or
likeness depicted in a Work;
iv. rights protecting against unfair competition in regards to a Work,
subject to the limitations in paragraph 4(a), below;
v. rights protecting the extraction, dissemination, use and reuse of data
in a Work;
vi. database rights (such as those arising under Directive 96/9/EC of the
European Parliament and of the Council of 11 March 1996 on the legal
protection of databases, and under any national implementation
thereof, including any amended or successor version of such
directive); and
vii. other similar, equivalent or corresponding rights throughout the
world based on applicable law or treaty, and any national
implementations thereof.
2. Waiver. To the greatest extent permitted by, but not in contravention
of, applicable law, Affirmer hereby overtly, fully, permanently,
irrevocably and unconditionally waives, abandons, and surrenders all of
Affirmer's Copyright and Related Rights and associated claims and causes
of action, whether now known or unknown (including existing as well as
future claims and causes of action), in the Work (i) in all territories
worldwide, (ii) for the maximum duration provided by applicable law or
treaty (including future time extensions), (iii) in any current or future
medium and for any number of copies, and (iv) for any purpose whatsoever,
including without limitation commercial, advertising or promotional
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
member of the public at large and to the detriment of Affirmer's heirs and
successors, fully intending that such Waiver shall not be subject to
revocation, rescission, cancellation, termination, or any other legal or
equitable action to disrupt the quiet enjoyment of the Work by the public
as contemplated by Affirmer's express Statement of Purpose.
3. Public License Fallback. Should any part of the Waiver for any reason
be judged legally invalid or ineffective under applicable law, then the
Waiver shall be preserved to the maximum extent permitted taking into
account Affirmer's express Statement of Purpose. In addition, to the
extent the Waiver is so judged Affirmer hereby grants to each affected
person a royalty-free, non transferable, non sublicensable, non exclusive,
irrevocable and unconditional license to exercise Affirmer's Copyright and
Related Rights in the Work (i) in all territories worldwide, (ii) for the
maximum duration provided by applicable law or treaty (including future
time extensions), (iii) in any current or future medium and for any number
of copies, and (iv) for any purpose whatsoever, including without
limitation commercial, advertising or promotional purposes (the
"License"). The License shall be deemed effective as of the date CC0 was
applied by Affirmer to the Work. Should any part of the License for any
reason be judged legally invalid or ineffective under applicable law, such
partial invalidity or ineffectiveness shall not invalidate the remainder
of the License, and in such case Affirmer hereby affirms that he or she
will not (i) exercise any of his or her remaining Copyright and Related
Rights in the Work or (ii) assert any associated claims and causes of
action with respect to the Work, in either case contrary to Affirmer's
express Statement of Purpose.
4. Limitations and Disclaimers.
a. No trademark or patent rights held by Affirmer are waived, abandoned,
surrendered, licensed or otherwise affected by this document.
b. Affirmer offers the Work as-is and makes no representations or
warranties of any kind concerning the Work, express, implied,
statutory or otherwise, including without limitation warranties of
title, merchantability, fitness for a particular purpose, non
infringement, or the absence of latent or other defects, accuracy, or
the present or absence of errors, whether or not discoverable, all to
the greatest extent permissible under applicable law.
c. Affirmer disclaims responsibility for clearing rights of other persons
that may apply to the Work or any use thereof, including without
limitation any person's Copyright and Related Rights in the Work.
Further, Affirmer disclaims responsibility for obtaining any necessary
consents, permissions or other rights required for any use of the
Work.
d. Affirmer understands and acknowledges that Creative Commons is not a
party to this document and has no duty or obligation with respect to
this CC0 or use of the Work.

View File

@ -0,0 +1,210 @@
Eclipse Public License - v 1.0
THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC
LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM
CONSTITUTES RECIPIENTS ACCEPTANCE OF THIS AGREEMENT.
1. DEFINITIONS
"Contribution" means:
a) in the case of the initial Contributor, the initial code and documentation
distributed under this Agreement, and
b) in the case of each subsequent Contributor:
i) changes to the Program, and
ii) additions to the Program;
where such changes and/or additions to the Program originate from and are
distributed by that particular Contributor. A Contribution 'originates' from
a Contributor if it was added to the Program by such Contributor itself or
anyone acting on such Contributors behalf. Contributions do not include
additions to the Program which: (i) are separate modules of software
distributed in conjunction with the Program under their own license agreement,
and (ii) are not derivative works of the Program.
"Contributor" means any person or entity that distributes the Program.
"Licensed Patents " mean patent claims licensable by a Contributor which are
necessarily infringed by the use or sale of its Contribution alone or when
combined with the Program.
"Program" means the Contributions distributed in accordance with this Agreement.
"Recipient" means anyone who receives the Program under this Agreement,
including all Contributors.
2. GRANT OF RIGHTS
a) Subject to the terms of this Agreement, each Contributor hereby grants
Recipient a non-exclusive, worldwide, royalty-free copyright license to
reproduce, prepare derivative works of, publicly display, publicly perform,
distribute and sublicense the Contribution of such Contributor, if any, and
such derivative works, in source code and object code form.
b) Subject to the terms of this Agreement, each Contributor hereby grants
Recipient a non-exclusive, worldwide, royalty-free patent license under
Licensed Patents to make, use, sell, offer to sell, import and otherwise
transfer the Contribution of such Contributor, if any, in source code and
object code form. This patent license shall apply to the combination of the
Contribution and the Program if, at the time the Contribution is added by
the Contributor, such addition of the Contribution causes such combination
to be covered by the Licensed Patents. The patent license shall not apply
to any other combinations which include the Contribution. No hardware per
se is licensed hereunder.
c) Recipient understands that although each Contributor grants the licenses to
its Contributions set forth herein, no assurances are provided by any
Contributor that the Program does not infringe the patent or other
intellectual property rights of any other entity. Each Contributor disclaims
any liability to Recipient for claims brought by any other entity based on
infringement of intellectual property rights or otherwise. As a condition to
exercising the rights and licenses granted hereunder, each Recipient hereby
assumes sole responsibility to secure any other intellectual property rights
needed, if any. For example, if a third party patent license is required to
allow Recipient to distribute the Program, it is Recipients responsibility
to acquire that license before distributing the Program.
d) Each Contributor represents that to its knowledge it has sufficient copyright
rights in its Contribution, if any, to grant the copyright license set forth
in this Agreement.
3. REQUIREMENTS
A Contributor may choose to distribute the Program in object code form under
its own license agreement, provided that:
a) it complies with the terms and conditions of this Agreement; and
b) its license agreement:
i) effectively disclaims on behalf of all Contributors all warranties and
conditions, express and implied, including warranties or conditions of title
and non-infringement, and implied warranties or conditions of merchantability
and fitness for a particular purpose;
ii) effectively excludes on behalf of all Contributors all liability for damages,
including direct, indirect, special, incidental and consequential damages,
such as lost profits;
iii) states that any provisions which differ from this Agreement are offered by
that Contributor alone and not by any other party; and
iv) states that source code for the Program is available from such Contributor,
and informs licensees how to obtain it in a reasonable manner on or through
a medium customarily used for software exchange.
When the Program is made available in source code form:
a) it must be made available under this Agreement; and
b) a copy of this Agreement must be included with each copy of the Program.
Contributors may not remove or alter any copyright notices contained within the
Program.
Each Contributor must identify itself as the originator of its Contribution,
if any, in a manner that reasonably allows subsequent Recipients to identify
the originator of the Contribution.
4. COMMERCIAL DISTRIBUTION
Commercial distributors of software may accept certain responsibilities with
respect to end users, business partners and the like. While this license is
intended to facilitate the commercial use of the Program, the Contributor who
includes the Program in a commercial product offering should do so in a manner
which does not create potential liability for other Contributors. Therefore,
if a Contributor includes the Program in a commercial product offering, such
Contributor ("Commercial Contributor") hereby agrees to defend and indemnify
every other Contributor ("Indemnified Contributor") against any losses, damages
and costs (collectively "Losses") arising from claims, lawsuits and other legal
actions brought by a third party against the Indemnified Contributor to the
extent caused by the acts or omissions of such Commercial Contributor in
connection with its distribution of the Program in a commercial product
offering. The obligations in this section do not apply to any claims or Losses
relating to any actual or alleged intellectual property infringement. In order
to qualify, an Indemnified Contributor must: a) promptly notify the Commercial
Contributor in writing of such claim, and b) allow the Commercial Contributor
to control, and cooperate with the Commercial Contributor in, the defense and
any related settlement negotiations. The Indemnified Contributor may participate
in any such claim at its own expense.
For example, a Contributor might include the Program in a commercial product
offering, Product X. That Contributor is then a Commercial Contributor. If that
Commercial Contributor then makes performance claims, or offers warranties
related to Product X, those performance claims and warranties are such
Commercial Contributors responsibility alone. Under this section, the
Commercial Contributor would have to defend claims against the other
Contributors related to those performance claims and warranties, and if a
court requires any other Contributor to pay any damages as a result, the
Commercial Contributor must pay those damages.
5. NO WARRANTY
EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR
IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE,
NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each
Recipient is solely responsible for determining the appropriateness of using
and distributing the Program and assumes all risks associated with its exercise
of rights under this Agreement , including but not limited to the risks and
costs of program errors, compliance with applicable laws, damage to or loss of
data, programs or equipment, and unavailability or interruption of operations.
6. DISCLAIMER OF LIABILITY
EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY
CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION
LOST PROFITS), 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 OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF
ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
7. GENERAL
If any provision of this Agreement is invalid or unenforceable under applicable
law, it shall not affect the validity or enforceability of the remainder of the
terms of this Agreement, and without further action by the parties hereto, such
provision shall be reformed to the minimum extent necessary to make such
provision valid and enforceable.
If Recipient institutes patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Program itself
(excluding combinations of the Program with other software or hardware)
infringes such Recipients patent(s), then such Recipients rights granted
under Section 2(b) shall terminate as of the date such litigation is filed.
All Recipients rights under this Agreement shall terminate if it fails to
comply with any of the material terms or conditions of this Agreement and does
not cure such failure in a reasonable period of time after becoming aware of
such noncompliance. If all Recipients rights under this Agreement terminate,
Recipient agrees to cease use and distribution of the Program as soon as
reasonably practicable. However, Recipients obligations under this Agreement
and any licenses granted by Recipient relating to the Program shall continue
and survive.
Everyone is permitted to copy and distribute copies of this Agreement, but in
order to avoid inconsistency the Agreement is copyrighted and may only be
modified in the following manner. The Agreement Steward reserves the right to
publish new versions (including revisions) of this Agreement from time to time.
No one other than the Agreement Steward has the right to modify this Agreement.
The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation
may assign the responsibility to serve as the Agreement Steward to a suitable
separate entity. Each new version of the Agreement will be given a
distinguishing version number. The Program (including Contributions) may always
be distributed subject to the version of the Agreement under which it was
received. In addition, after a new version of the Agreement is published,
Contributor may elect to distribute the Program (including its Contributions)
under the new version. Except as expressly stated in Sections 2(a) and 2(b)
above, Recipient receives no rights or licenses to the intellectual property
of any Contributor under this Agreement, whether expressly, by implication,
estoppel or otherwise. All rights in the Program not expressly granted under
this Agreement are reserved.
This Agreement is governed by the laws of the State of New York and the
intellectual property laws of the United States of America. No party to this
Agreement will bring a legal action under this Agreement more than one year
after the cause of action arose. Each party waives its rights to a jury trial
in any resulting litigation.

View File

@ -0,0 +1,347 @@
The GNU General Public License (GPL)
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies of this license
document, but changing it is not allowed.
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 Library 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.
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., 59
Temple Place, Suite 330, Boston, MA 02111-1307 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 Library General Public
License instead of this License.
"CLASSPATH" EXCEPTION TO THE GPL
Certain source files distributed by Oracle America and/or its affiliates are
subject to the following clarification and special exception to the GPL, but
only where Oracle has expressly included in the particular source file's header
the words "Oracle designates this particular file as subject to the "Classpath"
exception as provided by Oracle in the LICENSE file that accompanied this code."
Linking this library statically or dynamically with other modules is making
a combined work based on this library. Thus, the terms and conditions of
the GNU General Public License cover the whole combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent modules,
and to copy and distribute the resulting executable under terms of your
choice, provided that you also meet, for each linked independent module,
the terms and conditions of the license of that module. An independent
module is a module which is not derived from or based on this library. If
you modify this library, you may extend this exception to your version of
the library, but you are not obligated to do so. If you do not wish to do
so, delete this exception statement from your version.

View File

@ -0,0 +1,165 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

View File

@ -0,0 +1,21 @@
MIT License
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,469 @@
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.]

View File

@ -0,0 +1,86 @@
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.

View File

@ -0,0 +1,121 @@
Creative Commons Legal Code
CC0 1.0 Universal
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
HEREUNDER.
Statement of Purpose
The laws of most jurisdictions throughout the world automatically confer
exclusive Copyright and Related Rights (defined below) upon the creator
and subsequent owner(s) (each and all, an "owner") of an original work of
authorship and/or a database (each, a "Work").
Certain owners wish to permanently relinquish those rights to a Work for
the purpose of contributing to a commons of creative, cultural and
scientific works ("Commons") that the public can reliably and without fear
of later claims of infringement build upon, modify, incorporate in other
works, reuse and redistribute as freely as possible in any form whatsoever
and for any purposes, including without limitation commercial purposes.
These owners may contribute to the Commons to promote the ideal of a free
culture and the further production of creative, cultural and scientific
works, or to gain reputation or greater distribution for their Work in
part through the use and efforts of others.
For these and/or other purposes and motivations, and without any
expectation of additional consideration or compensation, the person
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
is an owner of Copyright and Related Rights in the Work, voluntarily
elects to apply CC0 to the Work and publicly distribute the Work under its
terms, with knowledge of his or her Copyright and Related Rights in the
Work and the meaning and intended legal effect of CC0 on those rights.
1. Copyright and Related Rights. A Work made available under CC0 may be
protected by copyright and related or neighboring rights ("Copyright and
Related Rights"). Copyright and Related Rights include, but are not
limited to, the following:
i. the right to reproduce, adapt, distribute, perform, display,
communicate, and translate a Work;
ii. moral rights retained by the original author(s) and/or performer(s);
iii. publicity and privacy rights pertaining to a person's image or
likeness depicted in a Work;
iv. rights protecting against unfair competition in regards to a Work,
subject to the limitations in paragraph 4(a), below;
v. rights protecting the extraction, dissemination, use and reuse of data
in a Work;
vi. database rights (such as those arising under Directive 96/9/EC of the
European Parliament and of the Council of 11 March 1996 on the legal
protection of databases, and under any national implementation
thereof, including any amended or successor version of such
directive); and
vii. other similar, equivalent or corresponding rights throughout the
world based on applicable law or treaty, and any national
implementations thereof.
2. Waiver. To the greatest extent permitted by, but not in contravention
of, applicable law, Affirmer hereby overtly, fully, permanently,
irrevocably and unconditionally waives, abandons, and surrenders all of
Affirmer's Copyright and Related Rights and associated claims and causes
of action, whether now known or unknown (including existing as well as
future claims and causes of action), in the Work (i) in all territories
worldwide, (ii) for the maximum duration provided by applicable law or
treaty (including future time extensions), (iii) in any current or future
medium and for any number of copies, and (iv) for any purpose whatsoever,
including without limitation commercial, advertising or promotional
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
member of the public at large and to the detriment of Affirmer's heirs and
successors, fully intending that such Waiver shall not be subject to
revocation, rescission, cancellation, termination, or any other legal or
equitable action to disrupt the quiet enjoyment of the Work by the public
as contemplated by Affirmer's express Statement of Purpose.
3. Public License Fallback. Should any part of the Waiver for any reason
be judged legally invalid or ineffective under applicable law, then the
Waiver shall be preserved to the maximum extent permitted taking into
account Affirmer's express Statement of Purpose. In addition, to the
extent the Waiver is so judged Affirmer hereby grants to each affected
person a royalty-free, non transferable, non sublicensable, non exclusive,
irrevocable and unconditional license to exercise Affirmer's Copyright and
Related Rights in the Work (i) in all territories worldwide, (ii) for the
maximum duration provided by applicable law or treaty (including future
time extensions), (iii) in any current or future medium and for any number
of copies, and (iv) for any purpose whatsoever, including without
limitation commercial, advertising or promotional purposes (the
"License"). The License shall be deemed effective as of the date CC0 was
applied by Affirmer to the Work. Should any part of the License for any
reason be judged legally invalid or ineffective under applicable law, such
partial invalidity or ineffectiveness shall not invalidate the remainder
of the License, and in such case Affirmer hereby affirms that he or she
will not (i) exercise any of his or her remaining Copyright and Related
Rights in the Work or (ii) assert any associated claims and causes of
action with respect to the Work, in either case contrary to Affirmer's
express Statement of Purpose.
4. Limitations and Disclaimers.
a. No trademark or patent rights held by Affirmer are waived, abandoned,
surrendered, licensed or otherwise affected by this document.
b. Affirmer offers the Work as-is and makes no representations or
warranties of any kind concerning the Work, express, implied,
statutory or otherwise, including without limitation warranties of
title, merchantability, fitness for a particular purpose, non
infringement, or the absence of latent or other defects, accuracy, or
the present or absence of errors, whether or not discoverable, all to
the greatest extent permissible under applicable law.
c. Affirmer disclaims responsibility for clearing rights of other persons
that may apply to the Work or any use thereof, including without
limitation any person's Copyright and Related Rights in the Work.
Further, Affirmer disclaims responsibility for obtaining any necessary
consents, permissions or other rights required for any use of the
Work.
d. Affirmer understands and acknowledges that Creative Commons is not a
party to this document and has no duty or obligation with respect to
this CC0 or use of the Work.

View File

@ -0,0 +1,464 @@
/*
* Copyright 2012 dorkbox, llc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dorkbox.license;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import dorkbox.util.LocationResolver;
public class License implements Comparable<License> {
private static final Charset UTF_8 = Charset.forName("UTF-8");
private static final String LINE_SEPARATOR = System.getProperty("line.separator");
private static int maxLicenseFileSize = Integer.MAX_VALUE/16;
/**
* Returns the LICENSE text file, as a combo of the listed licenses. Duplicates are removed.
*/
public static String buildString(List<License> licenses) {
StringBuilder b = new StringBuilder();
// The FIRST one is always FIRST! (the rest are alphabetical)
License firstLicense = licenses.remove(0);
// remove dupes
Set<License> dedupe = new HashSet<License>(licenses);
licenses.add(0, firstLicense);
licenses = new ArrayList<License>(dedupe);
Collections.sort(licenses);
licenses.add(0, firstLicense);
String NL = LINE_SEPARATOR;
String HEADER = " - ";
String SPACER = " ";
String SPACR1 = " ";
String SPACR2 = " ";
boolean first = true;
for (License l : licenses) {
if (first) {
first = false;
} else {
b.append(NL).append(NL);
}
b.append(HEADER).append(l.name).append(" - ").append(l.type.getDescription()).append(NL);
if (l.urls != null) {
for (String s : l.urls) {
b.append(SPACER).append(s).append(NL);
}
}
if (l.copyrights != null) {
for (String s : l.copyrights) {
b.append(SPACER).append(s).append(NL);
}
}
if (l.authors != null) {
for (String s : l.authors) {
b.append(SPACR1).append(s).append(NL);
}
}
if (l.notes != null) {
for (String s : l.notes) {
b.append(SPACR2).append(s).append(NL);
}
}
}
return b.toString();
}
public static void install(File targetLocation) throws IOException {
if (targetLocation == null) {
throw new IllegalArgumentException("targetLocation cannot be null.");
}
// copy over full text licenses
Map<LicenseType, byte[]> licenseAsBytes = License.getActualLicensesAsBytes(null);
for (Entry<LicenseType, byte[]> entry : licenseAsBytes.entrySet()) {
LicenseType key = entry.getKey();
byte[] bytes = entry.getValue();
File targetLicenseFile = new File(targetLocation, "LICENSE." + key.getExtension());
FileOutputStream fileOutputStream = new FileOutputStream(targetLicenseFile);
copyStream(new ByteArrayInputStream(bytes), fileOutputStream);
fileOutputStream.close();
}
}
/**
* Install the listed license files + full text licenses into the target directory.
*/
public static void install(String targetLocation, List<License> licenses) throws IOException {
if (targetLocation == null) {
throw new IllegalArgumentException("targetLocation cannot be null.");
}
if (licenses == null || licenses.isEmpty()) {
throw new IllegalArgumentException("licenses cannot be null or empty");
}
install(new File(targetLocation), licenses);
}
/**
* Install the listed license files + full text licenses into the target directory.
*/
public static void install(File targetLocation, List<License> licenses) throws IOException {
if (targetLocation == null) {
throw new IllegalArgumentException("targetLocation cannot be null.");
}
if (licenses == null || licenses.isEmpty()) {
throw new IllegalArgumentException("licenses cannot be null or empty");
}
// remove all old license files
File[] listFiles = targetLocation.listFiles();
if (listFiles != null) {
for (File f : listFiles) {
if (f.isFile() && f.getName().startsWith("LICENSE.")) {
f.delete();
}
}
}
// create main license file
String licenseFile = License.buildString(licenses);
InputStream input = new ByteArrayInputStream(licenseFile.getBytes(UTF_8));
OutputStream output = new FileOutputStream(new File(targetLocation, "LICENSE"));
copyStream(input, output);
output.close();
// copy over full text licenses
Map<LicenseType, byte[]> licenseAsBytes = License.getActualLicensesAsBytes(licenses);
for (Entry<LicenseType, byte[]> entry : licenseAsBytes.entrySet()) {
LicenseType key = entry.getKey();
byte[] bytes = entry.getValue();
File targetLicenseFile = new File(targetLocation, "LICENSE." + key.getExtension());
FileOutputStream fileOutputStream = new FileOutputStream(targetLicenseFile);
copyStream(new ByteArrayInputStream(bytes), fileOutputStream);
fileOutputStream.close();
}
}
/**
* Install the listed license files + full text licenses into the target zip file.
*/
public static void install(ZipOutputStream zipOutputStream, List<License> licenses) throws IOException {
if (zipOutputStream == null) {
throw new IllegalArgumentException("zipOutputStream cannot be null.");
}
if (licenses == null || licenses.isEmpty()) {
throw new IllegalArgumentException("licenses cannot be null or empty");
}
long time = System.currentTimeMillis();
String licenseFile = License.buildString(licenses);
// WHAT IF LICENSE ALREADY EXISTS?!?!
ZipEntry zipEntry = new ZipEntry("LICENSE");
zipEntry.setTime(time);
zipOutputStream.putNextEntry(zipEntry);
ByteArrayInputStream input = new ByteArrayInputStream(licenseFile.getBytes(UTF_8));
copyStream(input, zipOutputStream);
zipOutputStream.closeEntry();
Map<LicenseType, byte[]> licenseAsBytes = License.getActualLicensesAsBytes(licenses);
for (Entry<LicenseType, byte[]> entry : licenseAsBytes.entrySet()) {
LicenseType key = entry.getKey();
byte[] bytes = entry.getValue();
zipEntry = new ZipEntry("LICENSE." + key.getExtension());
zipEntry.setTime(time);
zipOutputStream.putNextEntry(zipEntry);
zipOutputStream.write(bytes, 0, bytes.length);
zipOutputStream.closeEntry();
}
}
/**
* @param licenses if NULL, then it returns ALL of the license types
*/
private static Map<LicenseType, byte[]> getActualLicensesAsBytes(List<License> licenses) throws IOException {
// de-duplicate types
Set<LicenseType> types = new HashSet<LicenseType>(0);
if (licenses != null) {
for (License l : licenses) {
types.add(l.type);
}
} else {
for (LicenseType lt : LicenseType.values()) {
types.add(lt);
}
}
HashMap<LicenseType, byte[]> hashMap = new HashMap<LicenseType, byte[]>(types.size());
// look on disk, or look in a jar for the licenses.
// Either way, we want the BYTES of those files!
String rootPath = LocationResolver.get(License.class).getPath();
File rootFile = new File(rootPath);
String fileName = License.class.getCanonicalName();
int maxLicenseFileSize = License.maxLicenseFileSize;
// this is PRIMARILY when running in an IDE
if (rootFile.isDirectory()) {
String nameAsFile = fileName.replace('.', File.separatorChar).substring(0, fileName.lastIndexOf('.'));
String location = rootFile.getParent();
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(location).append(File.separator)
.append("src").append(File.separator)
.append(nameAsFile).append(File.separator)
.append("LICENSE.");
String baseName = stringBuilder.toString();
for (LicenseType lt : types) {
String pathname = baseName + lt.getExtension();
File f = new File(pathname);
if (f.length() > maxLicenseFileSize) {
throw new RuntimeException("WTF are you doing?!?");
}
FileInputStream input = new FileInputStream(f);
ByteArrayOutputStream output = new ByteArrayOutputStream((int) f.length());
copyStream(input, output);
input.close();
hashMap.put(lt, output.toByteArray());
}
} else if (rootPath.endsWith(".jar") && isZipFile(rootFile)) {
// have to go digging for it!
String nameAsFile = fileName.replace('.', '/').substring(0, fileName.lastIndexOf('.')+1);
HashMap<String, LicenseType> licenseNames = new HashMap<String, LicenseType>(types.size());
for (LicenseType l : types) {
licenseNames.put(nameAsFile + "LICENSE." + l.getExtension(), l);
}
ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(rootFile));
ZipEntry entry;
while ((entry = zipInputStream.getNextEntry()) != null) {
String name = entry.getName();
LicenseType licenseType = licenseNames.get(name);
if (licenseType != null) {
// read out bytes!
ByteArrayOutputStream output = new ByteArrayOutputStream(4096);
copyStream(zipInputStream, output);
hashMap.put(licenseType, output.toByteArray());
zipInputStream.closeEntry();
}
}
zipInputStream.close();
} else {
throw new IOException("Don't know what this is, but - KAPOW_ON_GET_CLASS_PATH");
}
return hashMap;
}
/**
* Copy the contents of the input stream to the output stream.
* <p>
* DOES NOT CLOSE THE STEAMS!
*/
private static <T extends OutputStream> T copyStream(InputStream inputStream, T outputStream) throws IOException {
byte[] buffer = new byte[4096];
int read = 0;
while ((read = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, read);
}
return outputStream;
}
/**
* @return true if the file is a zip/jar file
*/
private static boolean isZipFile(File file) {
byte[] ZIP_HEADER = { 'P', 'K', 0x3, 0x4 };
boolean isZip = true;
byte[] buffer = new byte[ZIP_HEADER.length];
RandomAccessFile raf = null;
try {
raf = new RandomAccessFile(file, "r");
raf.readFully(buffer);
for (int i = 0; i < ZIP_HEADER.length; i++) {
if (buffer[i] != ZIP_HEADER[i]) {
isZip = false;
break;
}
}
} catch (Exception e) {
isZip = false;
} finally {
if (raf != null) {
try {
raf.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return isZip;
}
public String name;
public LicenseType type;
public List<String> urls;
private List<String> copyrights;
private List<String> authors;
private List<String> notes;
public License(String licenseName, LicenseType licenseType) {
this.name = licenseName;
this.type = licenseType;
}
/** URL **/
public License u(String url) {
if (this.urls == null) {
this.urls = new ArrayList<String>();
}
this.urls.add(url);
return this;
}
/** COPYRIGHT **/
public License c(String copyright) {
if (this.copyrights == null) {
this.copyrights = new ArrayList<String>();
}
this.copyrights.add(copyright);
return this;
}
/** License_NOTE **/
public License n(String note) {
if (this.notes == null) {
this.notes = new ArrayList<String>();
}
this.notes.add(note);
return this;
}
/** AUTHOR **/
public License a(String author) {
if (this.authors == null) {
this.authors = new ArrayList<String>();
}
this.authors.add(author);
return this;
}
public License clear() {
if (this.urls != null) {
this.urls.clear();
}
if (this.copyrights != null) {
this.copyrights.clear();
}
if (this.authors != null) {
this.authors.clear();
}
if (this.notes != null) {
this.notes.clear();
}
return this;
}
/**
* ignore case when sorting these
*/
@Override
public int compareTo(License o) {
return this.name.toLowerCase().compareTo(o.name.toLowerCase());
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (this.name == null ? 0 : this.name.hashCode());
result = prime * result + (this.type == null ? 0 : this.type.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
License other = (License) obj;
if (this.name == null) {
if (other.name != null) {
return false;
}
} else if (!this.name.equals(other.name)) {
return false;
}
if (this.type != other.type) {
return false;
}
return true;
}
@Override
public String toString() {
return this.name;
}
}

View File

@ -0,0 +1,47 @@
/*
* Copyright 2012 dorkbox, llc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dorkbox.license;
public enum LicenseType {
APACHE("Apachev2", "Apache 2.0 License"),
BSD("BSD", "BSD License"), // same as New BSD
CC0("CC0", "CC0 License"),
EPL("EPLv1", "Eclipse Public License"),
GPLv2_CP("GPLv2_CP", "GPL v2 License, with Classpath exception"),
LGPLv3("LGPLv3", "LGPL v3 License"),
MIT("MIT", "MIT License"), // same as MIT X11
MPL("MPLv1.1", "Mozilla Public License"),
OFL("OFLv1.1", "SIL Open Font License"),
PUBLIC("Public", "Public Domain"), // not quite the same as CC0 (CC0 is better)
;
private final String name;
private final String description;
private LicenseType(String name, String description) {
this.name = name;
this.description = description;
}
/** This is the file name extension for the license file */
public String getExtension() {
return this.name;
}
public String getDescription() {
return this.description;
}
}