Initial import of OAK java build management
This commit is contained in:
commit
33ffb03aab
|
@ -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>
|
|
@ -0,0 +1,5 @@
|
||||||
|
/classes/
|
||||||
|
/staging/
|
||||||
|
*.ini
|
||||||
|
*.key
|
||||||
|
temp.lzma
|
|
@ -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>
|
|
@ -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
|
|
@ -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.
|
|
@ -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.
|
|
@ -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.
|
|
@ -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.
|
|
@ -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.
|
|
@ -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.
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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";
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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];
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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() + "]";
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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.
|
|
@ -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.
|
|
@ -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.
|
|
@ -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 RECIPIENT’S 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 Contributor’s 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 Recipient’s 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 Contributor’s 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 Recipient’s patent(s), then such Recipient’s rights granted
|
||||||
|
under Section 2(b) shall terminate as of the date such litigation is filed.
|
||||||
|
|
||||||
|
All Recipient’s 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 Recipient’s rights under this Agreement terminate,
|
||||||
|
Recipient agrees to cease use and distribution of the Program as soon as
|
||||||
|
reasonably practicable. However, Recipient’s 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.
|
|
@ -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.
|
|
@ -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.
|
|
@ -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.
|
|
@ -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.]
|
|
@ -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.
|
|
@ -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.
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue