diff --git a/.project b/.project new file mode 100644 index 0000000..6ecf8ba --- /dev/null +++ b/.project @@ -0,0 +1,11 @@ + + + zipeditor + + + + + + + + diff --git a/CVSROOT/checkoutlist b/CVSROOT/checkoutlist deleted file mode 100644 index 2921bff..0000000 --- a/CVSROOT/checkoutlist +++ /dev/null @@ -1,13 +0,0 @@ -# The "checkoutlist" file is used to support additional version controlled -# administrative files in $CVSROOT/CVSROOT, such as template files. -# -# The first entry on a line is a filename which will be checked out from -# the corresponding RCS file in the $CVSROOT/CVSROOT directory. -# The remainder of the line is an error message to use if the file cannot -# be checked out. -# -# File format: -# -# [][] -# -# comment lines begin with '#' diff --git a/CVSROOT/commitinfo b/CVSROOT/commitinfo deleted file mode 100644 index b19e7b7..0000000 --- a/CVSROOT/commitinfo +++ /dev/null @@ -1,15 +0,0 @@ -# The "commitinfo" file is used to control pre-commit checks. -# The filter on the right is invoked with the repository and a list -# of files to check. A non-zero exit of the filter program will -# cause the commit to be aborted. -# -# The first entry on a line is a regular expression which is tested -# against the directory that the change is being committed to, relative -# to the $CVSROOT. For the first match that is found, then the remainder -# of the line is the name of the filter to run. -# -# If the repository name does not match any of the regular expressions in this -# file, the "DEFAULT" line is used, if it is specified. -# -# If the name "ALL" appears as a regular expression it is always used -# in addition to the first matching regex or "DEFAULT". diff --git a/CVSROOT/config b/CVSROOT/config deleted file mode 100644 index 92c150b..0000000 --- a/CVSROOT/config +++ /dev/null @@ -1,21 +0,0 @@ -# Set this to "no" if pserver shouldn't check system users/passwords -#SystemAuth=no - -# Put CVS lock files in this directory rather than directly in the repository. -#LockDir=/var/lock/cvs - -# Set `TopLevelAdmin' to `yes' to create a CVS directory at the top -# level of the new working directory when using the `cvs checkout' -# command. -#TopLevelAdmin=no - -# Set `LogHistory' to `all' or `TOEFWUPCGMAR' to log all transactions to the -# history file, or a subset as needed (ie `TMAR' logs all write operations) -#LogHistory=TOEFWUPCGMAR - -# Set `RereadLogAfterVerify' to `always' (the default) to allow the verifymsg -# script to change the log message. Set it to `stat' to force CVS to verify# that the file has changed before reading it (this can take up to an extra -# second per directory being committed, so it is not recommended for large -# repositories. Set it to `never' (the previous CVS behavior) to prevent -# verifymsg scripts from changing the log message. -#RereadLogAfterVerify=always diff --git a/CVSROOT/cvswrappers b/CVSROOT/cvswrappers deleted file mode 100644 index e989b75..0000000 --- a/CVSROOT/cvswrappers +++ /dev/null @@ -1,19 +0,0 @@ -# This file affects handling of files based on their names. -# -# The -m option specifies whether CVS attempts to merge files. -# -# The -k option specifies keyword expansion (e.g. -kb for binary). -# -# Format of wrapper file ($CVSROOT/CVSROOT/cvswrappers or .cvswrappers) -# -# wildcard [option value][option value]... -# -# where option is one of -# -f from cvs filter value: path to filter -# -t to cvs filter value: path to filter -# -m update methodology value: MERGE or COPY -# -k expansion mode value: b, o, kkv, &c -# -# and value is a single-quote delimited value. -# For example: -#*.gif -k 'b' diff --git a/CVSROOT/editinfo b/CVSROOT/editinfo deleted file mode 100644 index d78886c..0000000 --- a/CVSROOT/editinfo +++ /dev/null @@ -1,21 +0,0 @@ -# The "editinfo" file is used to allow verification of logging -# information. It works best when a template (as specified in the -# rcsinfo file) is provided for the logging procedure. Given a -# template with locations for, a bug-id number, a list of people who -# reviewed the code before it can be checked in, and an external -# process to catalog the differences that were code reviewed, the -# following test can be applied to the code: -# -# Making sure that the entered bug-id number is correct. -# Validating that the code that was reviewed is indeed the code being -# checked in (using the bug-id number or a seperate review -# number to identify this particular code set.). -# -# If any of the above test failed, then the commit would be aborted. -# -# Actions such as mailing a copy of the report to each reviewer are -# better handled by an entry in the loginfo file. -# -# One thing that should be noted is the the ALL keyword is not -# supported. There can be only one entry that matches a given -# repository. diff --git a/CVSROOT/loginfo b/CVSROOT/loginfo deleted file mode 100644 index 537607d..0000000 --- a/CVSROOT/loginfo +++ /dev/null @@ -1,27 +0,0 @@ -# The "loginfo" file controls where "cvs commit" log information -# is sent. The first entry on a line is a regular expression which must match -# the directory that the change is being made to, relative to the -# $CVSROOT. If a match is found, then the remainder of the line is a filter -# program that should expect log information on its standard input. -# -# If the repository name does not match any of the regular expressions in this -# file, the "DEFAULT" line is used, if it is specified. -# -# If the name ALL appears as a regular expression it is always used -# in addition to the first matching regex or DEFAULT. -# -# You may specify a format string as part of the -# filter. The string is composed of a `%' followed -# by a single format character, or followed by a set of format -# characters surrounded by `{' and `}' as separators. The format -# characters are: -# -# s = file name -# V = old version number (pre-checkin) -# v = new version number (post-checkin) -# t = tag or branch name -# -# For example: -#DEFAULT (echo ""; id; echo %s; date; cat) >> $CVSROOT/CVSROOT/commitlog -# or -#DEFAULT (echo ""; id; echo %{sVv}; date; cat) >> $CVSROOT/CVSROOT/commitlog diff --git a/CVSROOT/modules b/CVSROOT/modules deleted file mode 100644 index cb9e9ef..0000000 --- a/CVSROOT/modules +++ /dev/null @@ -1,26 +0,0 @@ -# Three different line formats are valid: -# key -a aliases... -# key [options] directory -# key [options] directory files... -# -# Where "options" are composed of: -# -i prog Run "prog" on "cvs commit" from top-level of module. -# -o prog Run "prog" on "cvs checkout" of module. -# -e prog Run "prog" on "cvs export" of module. -# -t prog Run "prog" on "cvs rtag" of module. -# -u prog Run "prog" on "cvs update" of module. -# -d dir Place module in directory "dir" instead of module name. -# -l Top-level directory only -- do not recurse. -# -# NOTE: If you change any of the "Run" options above, you'll have to -# release and re-checkout any working directories of these modules. -# -# And "directory" is a path to a directory relative to $CVSROOT. -# -# The "-a" option specifies an alias. An alias is interpreted as if -# everything on the right of the "-a" had been typed on the command line. -# -# You can encode a module within a module by using the special '&' -# character to interpose another module into the current module. This -# can be useful for creating a module that consists of many directories -# spread out over the entire source repository. diff --git a/CVSROOT/notify b/CVSROOT/notify deleted file mode 100644 index 74ae6f9..0000000 --- a/CVSROOT/notify +++ /dev/null @@ -1,12 +0,0 @@ -# The "notify" file controls where notifications from watches set by -# "cvs watch add" or "cvs edit" are sent. The first entry on a line is -# a regular expression which is tested against the directory that the -# change is being made to, relative to the $CVSROOT. If it matches, -# then the remainder of the line is a filter program that should contain -# one occurrence of %s for the user to notify, and information on its -# standard input. -# -# "ALL" or "DEFAULT" can be used in place of the regular expression. -# -# For example: -#ALL mail -s "CVS notification" %s diff --git a/CVSROOT/rcsinfo b/CVSROOT/rcsinfo deleted file mode 100644 index 49e59f4..0000000 --- a/CVSROOT/rcsinfo +++ /dev/null @@ -1,13 +0,0 @@ -# The "rcsinfo" file is used to control templates with which the editor -# is invoked on commit and import. -# -# The first entry on a line is a regular expression which is tested -# against the directory that the change is being made to, relative to the -# $CVSROOT. For the first match that is found, then the remainder of the -# line is the name of the file that contains the template. -# -# If the repository name does not match any of the regular expressions in this -# file, the "DEFAULT" line is used, if it is specified. -# -# If the name "ALL" appears as a regular expression it is always used -# in addition to the first matching regex or "DEFAULT". diff --git a/CVSROOT/taginfo b/CVSROOT/taginfo deleted file mode 100644 index 274a46d..0000000 --- a/CVSROOT/taginfo +++ /dev/null @@ -1,20 +0,0 @@ -# The "taginfo" file is used to control pre-tag checks. -# The filter on the right is invoked with the following arguments: -# -# $1 -- tagname -# $2 -- operation "add" for tag, "mov" for tag -F, and "del" for tag -d -# $3 -- repository -# $4-> file revision [file revision ...] -# -# A non-zero exit of the filter program will cause the tag to be aborted. -# -# The first entry on a line is a regular expression which is tested -# against the directory that the change is being committed to, relative -# to the $CVSROOT. For the first match that is found, then the remainder -# of the line is the name of the filter to run. -# -# If the repository name does not match any of the regular expressions in this -# file, the "DEFAULT" line is used, if it is specified. -# -# If the name "ALL" appears as a regular expression it is always used -# in addition to the first matching regex or "DEFAULT". diff --git a/CVSROOT/verifymsg b/CVSROOT/verifymsg deleted file mode 100644 index 86f747c..0000000 --- a/CVSROOT/verifymsg +++ /dev/null @@ -1,21 +0,0 @@ -# The "verifymsg" file is used to allow verification of logging -# information. It works best when a template (as specified in the -# rcsinfo file) is provided for the logging procedure. Given a -# template with locations for, a bug-id number, a list of people who -# reviewed the code before it can be checked in, and an external -# process to catalog the differences that were code reviewed, the -# following test can be applied to the code: -# -# Making sure that the entered bug-id number is correct. -# Validating that the code that was reviewed is indeed the code being -# checked in (using the bug-id number or a seperate review -# number to identify this particular code set.). -# -# If any of the above test failed, then the commit would be aborted. -# -# Actions such as mailing a copy of the report to each reviewer are -# better handled by an entry in the loginfo file. -# -# One thing that should be noted is the the ALL keyword is not -# supported. There can be only one entry that matches a given -# repository. diff --git a/ZipEditor Feature/.cvsignore b/ZipEditor Feature/.cvsignore deleted file mode 100644 index 32c5ac0..0000000 --- a/ZipEditor Feature/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -*.jar -build.xml diff --git a/ZipEditor Feature/META-INF/MANIFEST.MF b/ZipEditor Feature/META-INF/MANIFEST.MF deleted file mode 100644 index 59499bc..0000000 --- a/ZipEditor Feature/META-INF/MANIFEST.MF +++ /dev/null @@ -1,2 +0,0 @@ -Manifest-Version: 1.0 - diff --git a/ZipEditor Feature/build.properties b/ZipEditor Feature/build.properties deleted file mode 100644 index 4a89e32..0000000 --- a/ZipEditor Feature/build.properties +++ /dev/null @@ -1,3 +0,0 @@ -bin.includes = feature.xml,\ - cpl10.txt,\ - feature.properties diff --git a/ZipEditor Feature/feature.properties b/ZipEditor Feature/feature.properties deleted file mode 100644 index ec2a5d1..0000000 --- a/ZipEditor Feature/feature.properties +++ /dev/null @@ -1,240 +0,0 @@ -providerName=Uwe Voigt -featureName=ZipEditor -descriptionUrl=http://zipeditor.sourceforge.net/ -description=An Eclipse editor to manipulate archives.\n\ -1.1.9\n\ ----------------------\n\ -- Support search within non-archive files as well\n\ -1.1.8\n\ ----------------------\n\ -- Replaced some references to deprecated types/methods\n\ -1.1.7\n\ ----------------------\n\ -- https://sourceforge.net/p/zipeditor/bugs/14/ remove references to org.eclipse.jface.util.Assert\n\ -1.1.6\n\ ----------------------\n\ -- https://sourceforge.net/p/zipeditor/bugs/11/ disable debug by default\n\ -- https://sourceforge.net/p/zipeditor/bugs/12/ don't log too much\n\ -- https://sourceforge.net/p/zipeditor/bugs/13/ late opening of files\n\ -1.1.5\n\ ----------------------\n\ -- added RPM read functionality\n\ -- added method (compressed/stored) to zip entries\n\ -- save archive type specific editor settings\n\ -- general performance improvements\n\ -New in release 1.1.4\n\ ----------------------\n\ -- Ctrl+O in the editor opens a quick outline\n\ -- "Open in Zip Editor" can be used on build path entries\n\ -- Editors opened on search results show marker annotations for occurrences now.\ -\n\ -New in release 1.1.3\n\ ----------------------\n\ -- Use the Eclipse search to recursively search in archives. - -updateSiteName=ZipEditor Update Site - -copyright=© Uwe Voigt, 2006, 2007. All Rights Reserved. - -licenseURL=cpl10.txt - -license=\ -THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS \n\ -COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR \n\ -DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE \n\ -OF THIS AGREEMENT. \n\ -1. DEFINITIONS \n\ -"Contribution" means: \n\ -a) in the case of the initial Contributor, the initial code and \n\ -documentation distributed under this Agreement, and \n\ -b) in the case of each subsequent Contributor: \n\ -i) changes to the Program, and \n\ -ii) additions to the Program; \n\ -where such changes and/or additions to the Program originate \n\ -from and are distributed by that particular Contributor. A Contribution \n\ -'originates' from a Contributor if it was added to the Program \n\ -by such Contributor itself or anyone acting on such Contributor's \n\ -behalf. Contributions do not include additions to the Program \n\ -which:(i) are separate modules of software distributed in conjunction \n\ -with the Program under their own license agreement, and (ii) \n\ -are not derivative works of the Program. \n\ -"Contributor" means any person or entity that distributes the \n\ -Program. \n\ -"Licensed Patents " mean patent claims licensable by a Contributor \n\ -which are necessarily infringed by the use or sale of its Contribution \n\ -alone or when combined with the Program. \n\ -"Program" means the Contributions distributed in accordance with \n\ -this Agreement. \n\ -"Recipient" means anyone who receives the Program under this \n\ -Agreement, including all Contributors. \n\ -2. GRANT OF RIGHTS \n\ -a) Subject to the terms of this Agreement, each Contributor hereby \n\ -grants Recipient a non-exclusive, worldwide, royalty-free copyright \n\ -license to reproduce, prepare derivative works of, publicly display, \n\ -publicly perform, distribute and sublicense the Contribution \n\ -of such Contributor, if any, and such derivative works, in source \n\ -code and object code form. \n\ -b) Subject to the terms of this Agreement, each Contributor hereby \n\ -grants Recipient a non-exclusive, worldwide, royalty-free patent \n\ -license under Licensed Patents to make, use, sell, offer to sell, \n\ -import and otherwise transfer the Contribution of such Contributor, \n\ -if any, in source code and object code form. This patent license \n\ -shall apply to the combination of the Contribution and the Program \n\ -if, at the time the Contribution is added by the Contributor, \n\ -such addition of the Contribution causes such combination to \n\ -be covered by the Licensed Patents. The patent license shall \n\ -not apply to any other combinations which include the Contribution. \n\ -No hardware per se is licensed hereunder. \n\ -c) Recipient understands that although each Contributor grants \n\ -the licenses to its Contributions set forth herein, no assurances \n\ -are provided by any Contributor that the Program does not infringe \n\ -the patent or other intellectual property rights of any other \n\ -entity. Each Contributor disclaims any liability to Recipient \n\ -for claims brought by any other entity based on infringement \n\ -of intellectual property rights or otherwise. As a condition \n\ -to exercising the rights and licenses granted hereunder, each \n\ -Recipient hereby assumes sole responsibility to secure any other \n\ -intellectual property rights needed, if any. For example, if \n\ -a third party patent license is required to allow Recipient to \n\ -distribute the Program, it is Recipient's responsibility to acquire \n\ -that license before distributing the Program. \n\ -d) Each Contributor represents that to its knowledge it has sufficient \n\ -copyright rights in its Contribution, if any, to grant the copyright \n\ -license set forth in this Agreement. \n\ -3. REQUIREMENTS \n\ -A Contributor may choose to distribute the Program in object \n\ -code form under its own license agreement, provided that: \n\ -a) it complies with the terms and conditions of this Agreement; \n\ -and \n\ -b) its license agreement: \n\ -i) effectively disclaims on behalf of all Contributors all warranties \n\ -and conditions, express and implied, including warranties or \n\ -conditions of title and non-infringement, and implied warranties \n\ -or conditions of merchantability and fitness for a particular \n\ -purpose; \n\ -ii) effectively excludes on behalf of all Contributors all liability \n\ -for damages, including direct, indirect, special, incidental \n\ -and consequential damages, such as lost profits; \n\ -iii) states that any provisions which differ from this Agreement \n\ -are offered by that Contributor alone and not by any other party; \n\ -and \n\ -iv) states that source code for the Program is available from \n\ -such Contributor, and informs licensees how to obtain it in a \n\ -reasonable manner on or through a medium customarily used for \n\ -software exchange. \n\ -When the Program is made available in source code form: \n\ -a) it must be made available under this Agreement; and \n\ -b) a copy of this Agreement must be included with each copy of \n\ -the Program. \n\ -Contributors may not remove or alter any copyright notices contained \n\ -within the Program. \n\ -Each Contributor must identify itself as the originator of its \n\ -Contribution, if any, in a manner that reasonably allows subsequent \n\ -Recipients to identify the originator of the Contribution. \n\ -4. COMMERCIAL DISTRIBUTION \n\ -Commercial distributors of software may accept certain responsibilities \n\ -with respect to end users, business partners and the like. While \n\ -this license is intended to facilitate the commercial use of \n\ -the Program, the Contributor who includes the Program in a commercial \n\ -product offering should do so in a manner which does not create \n\ -potential liability for other Contributors. Therefore, if a Contributor \n\ -includes the Program in a commercial product offering, such Contributor \n\ -("Commercial Contributor") hereby agrees to defend and indemnify \n\ -every other Contributor ("Indemnified Contributor") against any \n\ -losses, damages and costs (collectively "Losses") arising from \n\ -claims, lawsuits and other legal actions brought by a third party \n\ -against the Indemnified Contributor to the extent caused by the \n\ -acts or omissions of such Commercial Contributor in connection \n\ -with its distribution of the Program in a commercial product \n\ -offering. The obligations in this section do not apply to any \n\ -claims or Losses relating to any actual or alleged intellectual \n\ -property infringement. In order to qualify, an Indemnified Contributor \n\ -must: a) promptly notify the Commercial Contributor in writing \n\ -of such claim, and b) allow the Commercial Contributor to control, \n\ -and cooperate with the Commercial Contributor in, the defense \n\ -and any related settlement negotiations. The Indemnified Contributor \n\ -may participate in any such claim at its own expense. \n\ -For example, a Contributor might include the Program in a commercial \n\ -product offering, Product X. That Contributor is then a Commercial \n\ -Contributor. If that Commercial Contributor then makes performance \n\ -claims, or offers warranties related to Product X, those performance \n\ -claims and warranties are such Commercial Contributor's responsibility \n\ -alone. Under this section, the Commercial Contributor would have \n\ -to defend claims against the other Contributors related to those \n\ -performance claims and warranties, and if a court requires any \n\ -other Contributor to pay any damages as a result, the Commercial \n\ -Contributor must pay those damages. \n\ -5. NO WARRANTY \n\ -EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM \n\ -IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS \n\ -OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, \n\ -ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY \n\ -OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely \n\ -responsible for determining the appropriateness of using and \n\ -distributing the Program and assumes all risks associated with \n\ -its exercise of rights under this Agreement, including but not \n\ -limited to the risks and costs of program errors, compliance \n\ -with applicable laws, damage to or loss of data, programs or \n\ -equipment, and unavailability or interruption of operations. \n\ -6. DISCLAIMER OF LIABILITY \n\ -EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT \n\ -NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, \n\ -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \n\ -(INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND \n\ -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, \n\ -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY \n\ -OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE \n\ -OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY \n\ -OF SUCH DAMAGES. \n\ -7. GENERAL \n\ -If any provision of this Agreement is invalid or unenforceable \n\ -under applicable law, it shall not affect the validity or enforceability \n\ -of the remainder of the terms of this Agreement, and without \n\ -further action by the parties hereto, such provision shall be \n\ -reformed to the minimum extent necessary to make such provision \n\ -valid and enforceable. \n\ -If Recipient institutes patent litigation against a Contributor \n\ -with respect to a patent applicable to software (including a \n\ -cross-claim or counterclaim in a lawsuit), then any patent licenses \n\ -granted by that Contributor to such Recipient under this Agreement \n\ -shall terminate as of the date such litigation is filed. In addition, \n\ -if Recipient institutes patent litigation against any entity \n\ -(including a cross-claim or counterclaim in a lawsuit) alleging \n\ -that the Program itself (excluding combinations of the Program \n\ -with other software or hardware) infringes such Recipient's patent(s), \n\ -then such Recipient's rights granted under Section 2(b) shall \n\ -terminate as of the date such litigation is filed. \n\ -All Recipient's rights under this Agreement shall terminate if \n\ -it fails to comply with any of the material terms or conditions \n\ -of this Agreement and does not cure such failure in a reasonable \n\ -period of time after becoming aware of such noncompliance. If \n\ -all Recipient's rights under this Agreement terminate, Recipient \n\ -agrees to cease use and distribution of the Program as soon as \n\ -reasonably practicable. However, Recipient's obligations under \n\ -this Agreement and any licenses granted by Recipient relating \n\ -to the Program shall continue and survive. \n\ -Everyone is permitted to copy and distribute copies of this Agreement, \n\ -but in order to avoid inconsistency the Agreement is copyrighted \n\ -and may only be modified in the following manner. The Agreement \n\ -Steward reserves the right to publish new versions (including \n\ -revisions) of this Agreement from time to time. No one other \n\ -than the Agreement Steward has the right to modify this Agreement. \n\ -IBM is the initial Agreement Steward. IBM may assign the responsibility \n\ -to serve as the Agreement Steward to a suitable separate entity. \n\ -Each new version of the Agreement will be given a distinguishing \n\ -version number. The Program (including Contributions) may always \n\ -be distributed subject to the version of the Agreement under \n\ -which it was received. In addition, after a new version of the \n\ -Agreement is published, Contributor may elect to distribute the \n\ -Program (including its Contributions) under the new version. \n\ -Except as expressly stated in Sections 2(a) and 2(b) above, Recipient \n\ -receives no rights or licenses to the intellectual property of \n\ -any Contributor under this Agreement, whether expressly, by implication, \n\ -estoppel or otherwise. All rights in the Program not expressly \n\ -granted under this Agreement are reserved. \n\ -This Agreement is governed by the laws of the State of New York \n\ -and the intellectual property laws of the United States of America. \n\ -No party to this Agreement will bring a legal action under this \n\ -Agreement more than one year after the cause of action arose. \n\ -Each party waives its rights to a jury trial in any resulting \n\ -litigation. \n\ diff --git a/ZipEditor Feature/feature.xml b/ZipEditor Feature/feature.xml deleted file mode 100644 index 88a0ce3..0000000 --- a/ZipEditor Feature/feature.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - %description - - - - %copyright - - - - %license - - - - - - - - - diff --git a/ZipEditor Update Site/site.xml b/ZipEditor Update Site/site.xml index e036dc6..302016e 100644 --- a/ZipEditor Update Site/site.xml +++ b/ZipEditor Update Site/site.xml @@ -3,7 +3,7 @@ ZipEditor list of features - + diff --git a/ZipEditor-test/.classpath b/ZipEditor-test/.classpath index 887e062..ff8b063 100644 --- a/ZipEditor-test/.classpath +++ b/ZipEditor-test/.classpath @@ -1,7 +1,7 @@ - - - - - - - + + + + + + + diff --git a/ZipEditor-test/.settings/org.eclipse.jdt.core.prefs b/ZipEditor-test/.settings/org.eclipse.jdt.core.prefs index 0c13c15..3b643fa 100644 --- a/ZipEditor-test/.settings/org.eclipse.jdt.core.prefs +++ b/ZipEditor-test/.settings/org.eclipse.jdt.core.prefs @@ -1,7 +1,12 @@ -#Sun Dec 04 11:24:59 CET 2011 eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=21 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=21 diff --git a/ZipEditor-test/META-INF/MANIFEST.MF b/ZipEditor-test/META-INF/MANIFEST.MF index 0e8e546..32c3600 100644 --- a/ZipEditor-test/META-INF/MANIFEST.MF +++ b/ZipEditor-test/META-INF/MANIFEST.MF @@ -9,6 +9,11 @@ Require-Bundle: org.eclipse.core.runtime, org.eclipse.core.filesystem, org.eclipse.search, ZipEditor, - org.junit + org.junit, + org.apache.commons.commons-compress, + org.apache.commons.commons-io;bundle-version="2.16.1", + org.eclipse.ui;bundle-version="3.206.0" +Import-Package: io.airlift.compress;version="[2.0.0,3.0.0)";resolution:=optional, + io.airlift.compress.zstd;version="[2.0.0,3.0.0)";resolution:=optional Eclipse-LazyStart: false Bundle-Vendor: %Bundle-Vendor.0 diff --git a/ZipEditor-test/resources/zstd.zip b/ZipEditor-test/resources/zstd.zip new file mode 100644 index 0000000..292603f Binary files /dev/null and b/ZipEditor-test/resources/zstd.zip differ diff --git a/ZipEditor-test/src/zipeditor/model/AbstractModelTest.java b/ZipEditor-test/src/zipeditor/model/AbstractModelTest.java index fd79602..e861b94 100644 --- a/ZipEditor-test/src/zipeditor/model/AbstractModelTest.java +++ b/ZipEditor-test/src/zipeditor/model/AbstractModelTest.java @@ -6,9 +6,12 @@ import java.io.FileInputStream; import java.io.InputStream; +import org.eclipse.jface.preference.IPreferenceStore; import org.junit.Before; import org.junit.Test; +import zipeditor.PreferenceConstants; +import zipeditor.ZipEditorPlugin; import zipeditor.model.ZipContentDescriber.ContentTypeId; public abstract class AbstractModelTest { @@ -21,6 +24,9 @@ public abstract class AbstractModelTest { @Before public void before() throws Exception { + IPreferenceStore preferenceStore = ZipEditorPlugin.getDefault().getPreferenceStore(); + preferenceStore.setValue(PreferenceConstants.PREFIX_EDITOR + PreferenceConstants.ACTIVATE_ZSTD_LIB, true); + File path = new File("resources/" + getArchiveName()); InputStream inputStream = new FileInputStream(path); boolean readonly = false; diff --git a/ZipEditor-test/src/zipeditor/model/ZipModelZstdTest.java b/ZipEditor-test/src/zipeditor/model/ZipModelZstdTest.java new file mode 100644 index 0000000..09c4a3b --- /dev/null +++ b/ZipEditor-test/src/zipeditor/model/ZipModelZstdTest.java @@ -0,0 +1,99 @@ +package zipeditor.model; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import io.airlift.compress.zstd.ZstdInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; + +import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; +import org.apache.commons.compress.archivers.zip.ZipFile; +import org.apache.commons.compress.archivers.zip.ZipMethod; +import org.apache.commons.compress.compressors.zstandard.ZstdCompressorInputStream; +import org.eclipse.jface.preference.IPreferenceStore; +import org.junit.Test; + +import zipeditor.PreferenceConstants; +import zipeditor.ZipEditorPlugin; +import zipeditor.model.ZipContentDescriber.ContentTypeId; +import zipeditor.preferences.PreferenceUtils; + +public class ZipModelZstdTest extends AbstractModelTest { + + @Override + public String getArchiveName() { + return "zstd.zip"; + } + + @Override + public ContentTypeId getArchiveType() { + return ContentTypeId.ZIP_FILE; + } + + @Override + public void shouldOpenNodes() throws Exception { + assertEquals(getArchiveType(), model.getType()); + assertEquals("", model.getRoot().getPath()); + assertEquals(2, model.getRoot().getChildren().length); + + ZipNode childByName = (ZipNode) model.getRoot().getChildByName(".classpath", false); + assertEquals(".classpath", childByName.getName()); + assertEquals(childByName.getMethod(), ZipMethod.ZSTD.getCode()); + + childByName = (ZipNode) model.getRoot().getChildByName(".project", false); + assertEquals(".project", childByName.getName()); + assertEquals(childByName.getMethod(), ZipMethod.ZSTD.getCode()); + } + + @Test + public void extractZstdNode0() throws IOException { + File zipPath = model.getZipPath(); + ZipFile zipFile = ZipFile.builder().setFile(zipPath).get(); + ZipArchiveEntry entry = zipFile.getEntry(".project"); + InputStream inputStream = zipFile.getInputStream(entry); + assertTrue(inputStream instanceof ZstdCompressorInputStream); + + String string = new String(inputStream.readAllBytes()); + String[] split = string.split("\n"); + assertEquals("", split[0]); + assertEquals(23, split.length); + } + + @Test + public void extractZstdNode1() throws IOException { + File zipPath = model.getZipPath(); + ZipFile zipFile = ZipFile.builder().setZstdInputStreamFactory(ZstdInputStream::new).setFile(zipPath).get(); + ZipArchiveEntry entry = zipFile.getEntry(".project"); + InputStream inputStream = zipFile.getInputStream(entry); + assertTrue(inputStream instanceof ZstdInputStream); + + String string = new String(inputStream.readAllBytes()); + String[] split = string.split("\n"); + assertEquals("", split[0]); + assertEquals(23, split.length); + + ZipEditorPlugin.getDefault().getPreferenceStore() + .setValue(PreferenceConstants.PREFIX_EDITOR + PreferenceConstants.SELECTED_ZSTD_LIB, PreferenceUtils.AIRCOMPRESSOR); + + assertTrue(PreferenceUtils.isAircompressorSelected()); + assertFalse(PreferenceUtils.isJNIZstdSelected()); + ZipEditorPlugin.getDefault().getPreferenceStore() + .setValue(PreferenceConstants.PREFIX_EDITOR + PreferenceConstants.SELECTED_ZSTD_LIB, PreferenceUtils.JNI_LIBRARY); + assertFalse(PreferenceUtils.isAircompressorSelected()); + assertTrue(PreferenceUtils.isJNIZstdSelected()); + + zipPath = model.getZipPath(); + zipFile = ZipFile.builder().setFile(zipPath).get(); + entry = zipFile.getEntry(".project"); + inputStream = zipFile.getInputStream(entry); + assertTrue(inputStream instanceof ZstdCompressorInputStream); + + string = new String(inputStream.readAllBytes()); + split = string.split("\n"); + assertEquals("", split[0]); + assertEquals(23, split.length); + } +} diff --git a/ZipEditor.UpdateSite/.gitignore b/ZipEditor.UpdateSite/.gitignore new file mode 100644 index 0000000..b83d222 --- /dev/null +++ b/ZipEditor.UpdateSite/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/ZipEditor.UpdateSite/category.xml b/ZipEditor.UpdateSite/category.xml new file mode 100644 index 0000000..37f3ffd --- /dev/null +++ b/ZipEditor.UpdateSite/category.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/ZipEditor.UpdateSite/pom.xml b/ZipEditor.UpdateSite/pom.xml new file mode 100644 index 0000000..d49ec3c --- /dev/null +++ b/ZipEditor.UpdateSite/pom.xml @@ -0,0 +1,84 @@ + + + 4.0.0 + + com.github + ZipEditor.parent + 1.0.0-SNAPSHOT + .. + + + ZipEditor.site + eclipse-repository + + + + tycho-snapshots + https://repo.eclipse.org/content/repositories/tycho-snapshots + + + eclipse-maven-releases + https://repo.eclipse.org/content/repositories/releases + + + eclipse-cbi-releases + https://repo.eclipse.org/content/repositories/cbi-releases + + + maven-repository + https://repo1.maven.org/maven2 + + + apache-repository + https://repository.apache.org/content/repositories/snapshots + + true + + + + + + localtarget + file:/${project.basedir}/../maven-bnd/site/target/repository/ + p2 + + + eclipse 2025-06 + http://download.eclipse.org/releases/2025-06 + p2 + + + apache-repository + https://repository.apache.org/content/repositories/snapshots + + true + + + + + + + org.eclipse.tycho + tycho-p2-repository-plugin + ${tycho-version} + + Zip Editor Repository + false + true + false + false + + + + org.eclipse.tycho + tycho-maven-plugin + true + + + + + + diff --git a/ZipEditor.targetPlatform/ZipEditor-Latest.target b/ZipEditor.targetPlatform/ZipEditor-Latest.target new file mode 100644 index 0000000..e6aed6d --- /dev/null +++ b/ZipEditor.targetPlatform/ZipEditor-Latest.target @@ -0,0 +1,97 @@ + + + + + + + + + + io.airlift + aircompressor + 2.0.2 + jar + + + + + Id1 + https://repo1.maven.org/maven2/ + + + + + + + + org.apache.commons + commons-compress + 1.28.0-SNAPSHOT + jar + + + org.apache.commons + commons-lang3 + 3.18.0-SNAPSHOT + jar + + + + + apache snapshot + https://repository.apache.org/content/repositories/snapshots/ + + + + + + + + com.github.luben + zstd-jni + 1.5.7-2 + jar + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ZipEditor.targetPlatform/pom.xml b/ZipEditor.targetPlatform/pom.xml new file mode 100644 index 0000000..c210e14 --- /dev/null +++ b/ZipEditor.targetPlatform/pom.xml @@ -0,0 +1,60 @@ + + + + 4.0.0 + + com.github + ZipEditor.parent + 1.0.0-SNAPSHOT + .. + + ZipEditor.targetPlatform + eclipse-target-definition + + + + + org.eclipse.tycho + tycho-maven-plugin + true + + + + + + + tycho-snapshots + https://repo.eclipse.org/content/repositories/tycho-snapshots + + + + eclipse-maven-releases + https://repo.eclipse.org/content/repositories/releases + + + + eclipse-cbi-releases + https://repo.eclipse.org/content/repositories/cbi-releases + + + maven-repository + https://repo1.maven.org/maven2 + + + apache-repository + https://repository.apache.org/content/repositories/snapshots + + true + + + + diff --git a/ZipEditor/.classpath b/ZipEditor/.classpath index 809a8f3..97bf0dc 100644 --- a/ZipEditor/.classpath +++ b/ZipEditor/.classpath @@ -1,11 +1,7 @@ - - - - - + diff --git a/ZipEditor/.gitignore b/ZipEditor/.gitignore index ae3c172..09e3bc9 100644 --- a/ZipEditor/.gitignore +++ b/ZipEditor/.gitignore @@ -1 +1,2 @@ /bin/ +/target/ diff --git a/ZipEditor/.settings/org.eclipse.jdt.core.prefs b/ZipEditor/.settings/org.eclipse.jdt.core.prefs index 7dae8f9..4fe4ac7 100644 --- a/ZipEditor/.settings/org.eclipse.jdt.core.prefs +++ b/ZipEditor/.settings/org.eclipse.jdt.core.prefs @@ -10,9 +10,9 @@ org.eclipse.jdt.core.codeComplete.staticFieldSuffixes= org.eclipse.jdt.core.codeComplete.staticFinalFieldPrefixes= org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes= org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.compliance=21 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate @@ -24,6 +24,7 @@ org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled org.eclipse.jdt.core.compiler.problem.discouragedReference=warning org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled org.eclipse.jdt.core.compiler.problem.enumIdentifier=warning org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore @@ -47,6 +48,7 @@ org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled @@ -69,4 +71,4 @@ org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disa org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning org.eclipse.jdt.core.compiler.release=enabled -org.eclipse.jdt.core.compiler.source=1.8 +org.eclipse.jdt.core.compiler.source=21 diff --git a/ZipEditor/META-INF/MANIFEST.MF b/ZipEditor/META-INF/MANIFEST.MF index 0cd6c46..491f9b2 100644 --- a/ZipEditor/META-INF/MANIFEST.MF +++ b/ZipEditor/META-INF/MANIFEST.MF @@ -2,9 +2,11 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Automatic-Module-Name: %Bundle-Name.0 Bundle-Name: %Bundle-Name.0 +Bundle-RequiredExecutionEnvironment: JavaSE-21 Bundle-SymbolicName: ZipEditor;singleton:=true -Bundle-Version: 1.1.9.qualifier +Bundle-Version: 1.2.1.qualifier Bundle-Activator: zipeditor.ZipEditorPlugin +Bundle-ClassPath: . Bundle-Localization: plugin Require-Bundle: org.eclipse.core.runtime, org.eclipse.core.resources, @@ -18,10 +20,14 @@ Require-Bundle: org.eclipse.core.runtime, org.eclipse.search, org.apache.ant, org.apache.commons.commons-io, - org.apache.commons.commons-compress;bundle-version="1.27.1", - org.apache.commons.lang3;bundle-version="3.17.0" + org.apache.commons.lang3;bundle-version="3.17.0", + org.apache.commons.commons-compress;bundle-version="1.28.0", + com.github.luben.zstd-jni;bundle-version="1.5.7";resolution:=optional Bundle-ActivationPolicy: lazy Bundle-Vendor: %Bundle-Vendor.0 Export-Package: zipeditor, zipeditor.model, + zipeditor.preferences, zipeditor.search +Import-Package: io.airlift.compress;version="[2.0.0,3.0.0)";resolution:=optional, + io.airlift.compress.zstd;version="[2.0.0,3.0.0)";resolution:=optional diff --git a/ZipEditor/build.properties b/ZipEditor/build.properties index 6335005..c07148f 100644 --- a/ZipEditor/build.properties +++ b/ZipEditor/build.properties @@ -1,5 +1,5 @@ source.. = src/ -output.. = bin/ +output.. = target/ bin.includes = META-INF/,\ .,\ plugin.xml,\ diff --git a/ZipEditor/category.xml b/ZipEditor/category.xml new file mode 100644 index 0000000..9bd4112 --- /dev/null +++ b/ZipEditor/category.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/ZipEditor/latest.target b/ZipEditor/latest.target new file mode 100644 index 0000000..e1d4ee7 --- /dev/null +++ b/ZipEditor/latest.target @@ -0,0 +1,17 @@ + + + + + + + + + x86_64 + linux + gtk + en_US + + + -Declipse.p2.max.threads=10 -Doomph.update.url=https://download.eclipse.org/oomph/updates/milestone/latest -Doomph.redirection.index.redirection=index:/->https://raw.githubusercontent.com/eclipse-oomph/oomph/master/setups/ -XX:CompileCommand=exclude org.eclipse.jdt.internal.core.dom.rewrite.ASTRewriteAnalyzer::getExtendedRange -Dorg.eclipse.ecf.provider.filetransfer.excludeContributors=org.eclipse.ecf.provider.filetransfer.httpclientjava -Dosgi.requiredJavaVersion=21 -Dosgi.instance.area.default=@user.home/eclipse-workspace -Dosgi.dataAreaRequiresExplicitInit=true -Dorg.eclipse.swt.graphics.Resource.reportNonDisposed=true -Declipse.e4.inject.javax.warning=false -Dorg.slf4j.simpleLogger.defaultLogLevel=off -Dsun.java.command=Eclipse -XX:+UseG1GC -XX:+UseStringDeduplication --add-modules=ALL-SYSTEM -Doomph.redirection.orbit.simrel.setup=https://raw.githubusercontent.com/eclipse-orbit/orbit-simrel/main/OrbitSimRel.setup->file:/home/mkaraman/eclipse/committers-2025-06/git/orbit-simrel/OrbitSimRel.setup -Xmx2048m + + \ No newline at end of file diff --git a/ZipEditor/plugin.xml b/ZipEditor/plugin.xml index 303a656..c683bc0 100644 --- a/ZipEditor/plugin.xml +++ b/ZipEditor/plugin.xml @@ -320,5 +320,13 @@ menubarPath="group.open"/> + + + + diff --git a/ZipEditor/pom.xml b/ZipEditor/pom.xml new file mode 100644 index 0000000..11e05ed --- /dev/null +++ b/ZipEditor/pom.xml @@ -0,0 +1,89 @@ + + 4.0.0 + + + ZipEditor + eclipse-plugin + 1.2.1-SNAPSHOT + + com.github + ../ + 1.0.0-SNAPSHOT + ZipEditor.parent + + + + + + + org.eclipse.tycho + tycho-source-plugin + ${tycho-version} + + + attach-sources + + plugin-source + + + + + + org.eclipse.tycho + tycho-maven-plugin + true + + + + true + ${project.basedir}/../maven-bnd/tp/MavenBND.target + include + + + + + + + + + + eclipse 2025-06 + http://download.eclipse.org/releases/2025-06 + p2 + + + localtarget + file:/${project.basedir}/../maven-bnd/site/target/repository/ + p2 + + + apache-repository + https://repository.apache.org/content/repositories/snapshots + true + + + + + + tycho-snapshots + https://repo.eclipse.org/content/repositories/tycho-snapshots + + + eclipse-maven-releases + https://repo.eclipse.org/content/repositories/releases + + + eclipse-cbi-releases + https://repo.eclipse.org/content/repositories/cbi-releases + + + maven-repository + https://repo1.maven.org/maven2 + + + apache-repository + https://repository.apache.org/content/repositories/snapshots + true + + + \ No newline at end of file diff --git a/ZipEditor/src/zipeditor/LazyZipContentProvider.java b/ZipEditor/src/zipeditor/LazyZipContentProvider.java index e005849..d450a29 100644 --- a/ZipEditor/src/zipeditor/LazyZipContentProvider.java +++ b/ZipEditor/src/zipeditor/LazyZipContentProvider.java @@ -21,6 +21,9 @@ public LazyZipContentProvider(int mode) { } public int findElement(Object element) { + if (fTableViewer == null) { + return -1; + } IElementComparer comparer = fTableViewer.getComparer(); for (int i = 0; i < fRootChildren.length; i++) { if (comparer.equals(fRootChildren[i], element)) diff --git a/ZipEditor/src/zipeditor/PreferenceConstants.java b/ZipEditor/src/zipeditor/PreferenceConstants.java index bf7d477..9320353 100644 --- a/ZipEditor/src/zipeditor/PreferenceConstants.java +++ b/ZipEditor/src/zipeditor/PreferenceConstants.java @@ -26,6 +26,10 @@ public class PreferenceConstants { public final static String SORT_ENABLED = "SORT_ENABLED"; //$NON-NLS-1$ + public final static String ACTIVATE_ZSTD_LIB = "ACTIVE_ZSTD"; //$NON-NLS-1$ + + public static final String SELECTED_ZSTD_LIB = "selectedZstdLib"; //$NON-NLS-1$ + public final static String EXTERNAL_EDITORS = "EXTERNAL_EDITORS"; //$NON-NLS-1$ public final static String PREFIX_EDITOR = "editor"; //$NON-NLS-1$ @@ -46,6 +50,10 @@ public class PreferenceConstants { public final static String STORE_FOLDERS_IN_ARCHIVES = "storeFoldersInArchives"; //$NON-NLS-1$ + public static final String USE_ZSTD_AS_DEFAULT = "useZstdDefault"; //$NON-NLS-1$ + + public static final String COMPRESSION_LEVEL = "compressionLevel"; //$NON-NLS-1$ + public static String getPreferenceSuffix(ContentTypeId type) { switch (type.getOrdinal()) { case ContentTypeId.ZIP: diff --git a/ZipEditor/src/zipeditor/PreferenceInitializer.java b/ZipEditor/src/zipeditor/PreferenceInitializer.java index 9defd4b..d4fd9f2 100644 --- a/ZipEditor/src/zipeditor/PreferenceInitializer.java +++ b/ZipEditor/src/zipeditor/PreferenceInitializer.java @@ -13,6 +13,7 @@ import zipeditor.model.NodeProperty; import zipeditor.model.ZipContentDescriber.ContentTypeId; +import zipeditor.preferences.PreferenceUtils; public class PreferenceInitializer extends AbstractPreferenceInitializer { @@ -63,6 +64,9 @@ public void initializeDefaultPreferences() { store.setDefault(PreferenceConstants.PREFIX_NAVIGATOR + PreferenceConstants.SORT_ENABLED, true); store.setDefault(PreferenceConstants.PREFIX_EDITOR + PreferenceConstants.VIEW_MODE, PreferenceConstants.VIEW_MODE_FOLDERS_ONE_LAYER); store.setDefault(PreferenceConstants.PREFIX_EDITOR + PreferenceConstants.SORT_ENABLED, true); + store.setDefault(PreferenceConstants.PREFIX_EDITOR + PreferenceConstants.ACTIVATE_ZSTD_LIB, false); + store.setDefault(PreferenceConstants.PREFIX_EDITOR + PreferenceConstants.COMPRESSION_LEVEL, 10); + store.setDefault(PreferenceConstants.PREFIX_EDITOR + PreferenceConstants.USE_ZSTD_AS_DEFAULT, false); store.setDefault(PreferenceConstants.SORT_BY, defaultSortBy); store.setDefault(PreferenceConstants.SORT_DIRECTION, SWT.UP); store.setDefault(PreferenceConstants.VISIBLE_COLUMNS, defaultVisibleColumns); diff --git a/ZipEditor/src/zipeditor/ZipContentProvider.java b/ZipEditor/src/zipeditor/ZipContentProvider.java index 16edbad..cf39932 100644 --- a/ZipEditor/src/zipeditor/ZipContentProvider.java +++ b/ZipEditor/src/zipeditor/ZipContentProvider.java @@ -34,6 +34,9 @@ public Object[] getChildren(Object parentElement) { } protected Object[] getNodeChildren(Node node) { + if (node == null) { + return new Object[0]; + } if (fDisposeModel && fModel != node.getModel()) fModel = node.getModel(); if ((fMode & PreferenceConstants.VIEW_MODE_TREE) > 0) diff --git a/ZipEditor/src/zipeditor/ZipEditor.java b/ZipEditor/src/zipeditor/ZipEditor.java index 0e968b7..888cb8b 100644 --- a/ZipEditor/src/zipeditor/ZipEditor.java +++ b/ZipEditor/src/zipeditor/ZipEditor.java @@ -31,7 +31,9 @@ import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.SubMonitor; import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.jface.action.ActionContributionItem; import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IContributionItem; import org.eclipse.jface.action.IMenuListener; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.IToolBarManager; @@ -41,6 +43,8 @@ import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.resource.ImageDescriptor; @@ -64,6 +68,7 @@ import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.StackLayout; import org.eclipse.swt.dnd.DND; import org.eclipse.swt.dnd.FileTransfer; import org.eclipse.swt.dnd.Transfer; @@ -77,10 +82,12 @@ import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.Shell; @@ -100,8 +107,10 @@ import org.eclipse.ui.IWorkbenchActionConstants; import org.eclipse.ui.IWorkbenchPartSite; import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; import org.eclipse.ui.actions.ActionContext; import org.eclipse.ui.actions.ActionFactory; +import org.eclipse.ui.dialogs.PreferencesUtil; import org.eclipse.ui.dialogs.SaveAsDialog; import org.eclipse.ui.part.EditorPart; import org.eclipse.ui.part.FileEditorInput; @@ -113,7 +122,6 @@ import org.eclipse.ui.views.framelist.GoIntoAction; import org.eclipse.ui.views.framelist.UpAction; -import zipeditor.actions.ActionMessages; import zipeditor.actions.CollapseAllAction; import zipeditor.actions.NewFolderAction; import zipeditor.actions.OpenActionGroup; @@ -131,6 +139,7 @@ import zipeditor.model.NodeProperty; import zipeditor.model.ZipContentDescriber; import zipeditor.model.ZipContentDescriber.ContentTypeId; +import zipeditor.model.ZipEditorZstdException; import zipeditor.model.ZipModel; import zipeditor.model.ZipModel.IErrorReporter; import zipeditor.model.ZipNodeProperty; @@ -356,6 +365,9 @@ public void widgetDisposed(DisposeEvent e) { public final static String ACTION_GO_INTO = "GoInto"; //$NON-NLS-1$ public final static String ACTION_RENAME = "Rename"; //$NON-NLS-1$ public final static String ACTION_QUICK_OUTLINE = "QuickOutline"; //$NON-NLS-1$ + private Composite fControl; + private Composite fInvalidContent; + private StackLayout fStackLayout; public void doSave(IProgressMonitor monitor) { IEditorInput input = doGetEditorInput(); @@ -569,6 +581,9 @@ private ZipModel createModel() { public void reportError(IStatus message) { ZipEditorActionBarContributor contributor = (ZipEditorActionBarContributor) getEditorSite().getActionBarContributor(); + if (message.getException() instanceof ZipEditorZstdException) { + doShowErrorDialog(message.getException()); + } contributor.reportError(this, message); } @@ -639,11 +654,11 @@ public boolean isSaveAsAllowed() { } public void createPartControl(Composite parent) { - Composite control = new Composite(parent, SWT.NONE); + fControl = new Composite(parent, SWT.NONE); GridLayout layout = new GridLayout(); layout.marginWidth = layout.marginHeight = 0; - control.setLayout(layout); - createContent(control, getMode()); + fControl.setLayout(layout); + createContent(fControl, getMode()); } private void createContent(Composite parent, int mode) { @@ -656,9 +671,65 @@ private void createContent(Composite parent, int mode) { private void createControls(Composite parent, int mode) { fToolBar = createToolBar(parent); - fZipViewer = createZipViewer(parent, mode); + fStackLayout = new StackLayout(); + + Composite composite = new Composite(parent, SWT.NONE); + composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + composite.setLayout(fStackLayout); + + fZipViewer = createZipViewer(composite, mode); + fInvalidContent = createErrorHint(composite); + + handleStackLayout(); + } + + private void handleStackLayout() { + if (fModel.getType() == ContentTypeId.INVALID) { + fStackLayout.topControl = fInvalidContent; + fControl.layout(); + setEnablementOfUI(false); + + setEnabledOfControls(true, fInvalidContent); + } else { + fStackLayout.topControl = getViewer().getControl(); + fControl.layout(); + setEnablementOfUI(true); + } } + private Composite createErrorHint(Composite composite) { + Composite fErrorHintComposite = new Composite(composite, SWT.NONE); + GridDataFactory.fillDefaults().grab(true, true).align(SWT.FILL, SWT.FILL).applyTo(fErrorHintComposite); + GridLayoutFactory.fillDefaults().applyTo(fErrorHintComposite); + + Label label = new Label(fErrorHintComposite, SWT.WRAP | SWT.CENTER); + GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).grab(true, true).applyTo(label); + label.setText(Messages.getString("ZipEditor.15")); //$NON-NLS-1$ + + Button button = new Button(fErrorHintComposite, SWT.PUSH); + GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.TOP).grab(true, true).applyTo(button); + button.setText(Messages.getString("ZipEditor.16")); //$NON-NLS-1$ + button.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + openZipEditorPrefPage(); + } + }); + + return fErrorHintComposite; + } + + public void openZipEditorPrefPage() { + Window dialog = PreferencesUtil.createPreferenceDialogOn( + PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), + "zipeditor.preferences.ZipEditorPreferencePage", //$NON-NLS-1$ + null, + null); + if (dialog != null) { + dialog.open(); + } + } + private ToolBarManager createToolBar(Composite parent) { ToolBarManager bar = new ToolBarManager(SWT.HORIZONTAL | SWT.FLAT); Control control = bar.createControl(parent); @@ -683,22 +754,36 @@ private void fillToolBar(IToolBarManager bar, int mode) { bar.add(getAction(ACTION_COLLAPSE_ALL)); } bar.update(false); + if (fModel.getType() == ContentTypeId.INVALID) { + IContributionItem[] items = bar.getItems(); + for (IContributionItem iContributionItem : items) { + if (iContributionItem instanceof ActionContributionItem aci) { + aci.getAction().setEnabled(false); + } + } + } } public void updateView(int mode, boolean savePreferences) { - Composite parent = fZipViewer.getControl().getParent(); + Composite parent = fZipViewer.getControl().getParent().getParent(); ISelection selection = fZipViewer.getSelection(); ((ZipContentProvider) fZipViewer.getContentProvider()).disposeModel(false); Control[] children = parent.getChildren(); + // Attention: The dispose listener is attached to the viewer control and has to be removed directly from it + // due the change from getParent() to getParent().getParent() it wasn't possible to remove the listener from + // children arrays controls. + if (!savePreferences) + fZipViewer.getControl().removeDisposeListener(fTableDisposeListener); + for (int i = 0; i < children.length; i++) { - if (!savePreferences) - children[i].removeDisposeListener(fTableDisposeListener); children[i].dispose(); } createContent(parent, mode); fZipViewer.setSelection(selection); fZipViewer.getControl().setFocus(); ((ZipContentProvider) fZipViewer.getContentProvider()).disposeModel(true); + + handleStackLayout(); } private StructuredViewer createZipViewer(Composite parent, int mode) { @@ -794,6 +879,10 @@ private void setViewerInput(final StructuredViewer viewer) { } else { input = fModel.getRoot(); } + if (fModel.getType() == ContentTypeId.INVALID) { + return; + } + if (input != null) { if (Utils.isUIThread()) { doSetViewerInput(viewer, input); @@ -819,6 +908,31 @@ public void run() { } } + private void setEnablementOfUI(boolean enabled) { + Composite composite = fControl; + if (Utils.isUIThread()) { + setEnabledOfControls(enabled, composite); + } else { + Display.getDefault().syncExec(new Runnable() { + + @Override + public void run() { + setEnabledOfControls(enabled, composite); + } + }); + } + } + + private void setEnabledOfControls(boolean enabled, Composite composite) { + for (Control control : composite.getChildren()) { + if (control instanceof Composite childComposite) { + setEnabledOfControls(enabled, childComposite); + } else { + control.setEnabled(enabled); + } + } + } + private void doSetViewerInput(StructuredViewer viewer, Object input) { viewer.setInput(input); if (createColumns) { @@ -961,6 +1075,9 @@ public void widgetSelected(SelectionEvent e) { public void storeTableColumnPreferences() { if (!(fZipViewer instanceof TableViewer)) return; + if (fModel.getType() == ContentTypeId.INVALID) { + return; + } Table table = ((TableViewer) fZipViewer).getTable(); IPreferenceStore store = getPreferenceStore(); String suffix = PreferenceConstants.getPreferenceSuffix(fModel.getType()); @@ -1016,8 +1133,8 @@ private void createActions(int mode) { fZipActionGroup = new ZipActionGroup(this); fOpenActionGroup = new OpenActionGroup(getViewer()); setAction(ACTION_NEW_FOLDER, new NewFolderAction(getViewer())); - ToggleViewModeAction toggleViewModeAction = new ToggleViewModeAction(this, ActionMessages.getString("ToggleViewModeAction.0"), PreferenceConstants.PREFIX_EDITOR, PreferenceConstants.VIEW_MODE_TREE); //$NON-NLS-1$ - toggleViewModeAction.setToolTipText(ActionMessages.getString("ToggleViewModeAction.1")); //$NON-NLS-1$ + ToggleViewModeAction toggleViewModeAction = new ToggleViewModeAction(this, "", PreferenceConstants.PREFIX_EDITOR, PreferenceConstants.VIEW_MODE_TREE); //$NON-NLS-1$ + toggleViewModeAction.setToolTipText(""); //$NON-NLS-1$ toggleViewModeAction.setImageDescriptor(ZipEditorPlugin.getImageDescriptor("icons/togglemode.gif")); //$NON-NLS-1$ setAction(ACTION_TOGGLE_MODE, toggleViewModeAction); @@ -1118,7 +1235,9 @@ public void selectionChanged(SelectionChangedEvent event) { } getEditorSite().getShell().getDisplay().asyncExec(new Runnable() { public void run() { - fOutlinePage.setInput(fModel.getRoot()); + if(fOutlinePage != null && fModel != null) { + fOutlinePage.setInput(fModel.getRoot()); + } } }); return fOutlinePage; @@ -1215,8 +1334,22 @@ public int getMode() { } public void propertyChange(PropertyChangeEvent event) { - if ((PreferenceConstants.PREFIX_EDITOR + PreferenceConstants.SORT_ENABLED + SortAction.SORTING_CHANGED).equals(event.getProperty())) + if ((PreferenceConstants.PREFIX_EDITOR + PreferenceConstants.SORT_ENABLED + SortAction.SORTING_CHANGED).equals(event.getProperty())) { + updateView(getMode(), true); + } else if ((PreferenceConstants.PREFIX_EDITOR + PreferenceConstants.ACTIVATE_ZSTD_LIB).equals(event.getProperty())) { + fModel = null; + setViewerInput(fZipViewer); + getAdapter(IContentOutlinePage.class); + updateView(getMode(), true); + + } else if ((PreferenceConstants.PREFIX_EDITOR + PreferenceConstants.SELECTED_ZSTD_LIB).equals(event.getProperty())) { + fModel = null; + setViewerInput(fZipViewer); + getAdapter(IContentOutlinePage.class); + + updateView(getMode(), true); + } } public void saveState(IMemento memento) { diff --git a/ZipEditor/src/zipeditor/ZipEditorDropAdapter.java b/ZipEditor/src/zipeditor/ZipEditorDropAdapter.java index dfc4504..179d4e1 100644 --- a/ZipEditor/src/zipeditor/ZipEditorDropAdapter.java +++ b/ZipEditor/src/zipeditor/ZipEditorDropAdapter.java @@ -13,6 +13,7 @@ import org.eclipse.ui.part.PluginDropAdapter; import zipeditor.model.Node; +import zipeditor.model.zstd.ZstdUtilities; import zipeditor.operations.AddOperation; public class ZipEditorDropAdapter extends PluginDropAdapter { @@ -49,8 +50,8 @@ public boolean performDrop(Object data) { parentNode = parentNode.getParent(); String[] names = (String[]) data; AddOperation operation = new AddOperation(); - operation.execute(names, parentNode, selectedNode, (StructuredViewer) getViewer()); + boolean useZstdCompression = ZstdUtilities.useZstdCompression(parentNode); + operation.execute(names, parentNode, selectedNode, (StructuredViewer) getViewer(), useZstdCompression); return true; } - } diff --git a/ZipEditor/src/zipeditor/ZipNodePropertyPage.java b/ZipEditor/src/zipeditor/ZipNodePropertyPage.java index 08ee69f..b8744e6 100644 --- a/ZipEditor/src/zipeditor/ZipNodePropertyPage.java +++ b/ZipEditor/src/zipeditor/ZipNodePropertyPage.java @@ -2,6 +2,7 @@ import java.util.zip.ZipEntry; +import org.apache.commons.compress.archivers.zip.ZipMethod; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; @@ -11,6 +12,7 @@ import zipeditor.model.Node; import zipeditor.model.ZipNode; import zipeditor.model.ZipNodeProperty; +import zipeditor.preferences.PreferenceUtils; public class ZipNodePropertyPage extends NodePropertyPage implements IWorkbenchPropertyPage { private class MappingPropertyAccessor extends MultiplePropertyAccessor { @@ -38,6 +40,9 @@ protected Control createContents(Composite parent) { fMethod = createCombo(control, 30, 1); fMethod.add(Messages.getString("MappingPropertyAccessor.8")); //$NON-NLS-1$ fMethod.add(Messages.getString("MappingPropertyAccessor.0")); //$NON-NLS-1$ + if (PreferenceUtils.isZstdAvailableAndActive()) { + fMethod.add(Messages.getString("MappingPropertyAccessor.93")); //$NON-NLS-1$ + } select(fMethod, new MappingPropertyAccessor(ZipNode.class).getAccessor("method")); //$NON-NLS-1$ createLabel(control, ZipNodeProperty.PPACKED_SIZE.toString(), 1); fPackedSize = createText(control, 30, 1, false); @@ -90,6 +95,8 @@ public boolean performOk() { zipNode.setMethod(ZipEntry.DEFLATED); else if (method == 2) zipNode.setMethod(ZipEntry.STORED); + else if (method == 3) + zipNode.setMethod(ZipMethod.ZSTD.getCode()); } return true; } diff --git a/ZipEditor/src/zipeditor/actions/AddAction.java b/ZipEditor/src/zipeditor/actions/AddAction.java index a7a71ed..064e741 100644 --- a/ZipEditor/src/zipeditor/actions/AddAction.java +++ b/ZipEditor/src/zipeditor/actions/AddAction.java @@ -10,7 +10,10 @@ import zipeditor.ZipEditorPlugin; import zipeditor.model.Node; +import zipeditor.model.ZipContentDescriber.ContentTypeId; +import zipeditor.model.zstd.ZstdUtilities; import zipeditor.operations.AddOperation; +import zipeditor.preferences.PreferenceUtils; public class AddAction extends DialogAction { public AddAction(StructuredViewer viewer) { @@ -20,13 +23,13 @@ public AddAction(StructuredViewer viewer) { } public void run() { - File[] paths = openDialog(ActionMessages.getString("AddAction.2"), null, true, true); //$NON-NLS-1$); - if (paths == null || paths.length == 0) - return; Node[] selectedNodes = getSelectedNodes(); Node targetNode = selectedNodes.length > 0 ? selectedNodes[0] : getViewerInputAsNode(); + File[] paths = openDialog(ActionMessages.getString("AddAction.2"), null, true, true, PreferenceUtils.isZstdAvailableAndActive() && targetNode.getModel().getType() == ContentTypeId.ZIP_FILE); //$NON-NLS-1$); + if (paths == null || paths.length == 0) + return; AddOperation operation = new AddOperation(); - operation.execute(paths, targetNode, null, getViewer()); + operation.execute(paths, targetNode, null, getViewer(), ZstdUtilities.useZstdCompression(targetNode.getModel().getRoot())); } } diff --git a/ZipEditor/src/zipeditor/actions/DialogAction.java b/ZipEditor/src/zipeditor/actions/DialogAction.java index 9e2203f..7faa6ba 100644 --- a/ZipEditor/src/zipeditor/actions/DialogAction.java +++ b/ZipEditor/src/zipeditor/actions/DialogAction.java @@ -19,7 +19,10 @@ import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.SashForm; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; @@ -27,9 +30,12 @@ import org.eclipse.ui.PlatformUI; import zipeditor.ZipEditorPlugin; +import zipeditor.preferences.PreferenceUtils; public abstract class DialogAction extends ViewerAction { + private boolean zstdCompression = false; + private class FileDialog extends Dialog implements ISelectionChangedListener { private FileSystemChooseControl fWorkspaceViewer; private FileSystemChooseControl fFileSystemViewer; @@ -40,9 +46,11 @@ private class FileDialog extends Dialog implements ISelectionChangedListener { private boolean fMultiSelection; private boolean fShowFiles; private File fInitialSelection; + private boolean fAllowZstd; - private FileDialog(String text) { + private FileDialog(String text, boolean allowZstd) { super(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell()); + fAllowZstd = allowZstd; setShellStyle(getShellStyle() | SWT.SHELL_TRIM); fText = text; } @@ -68,6 +76,20 @@ protected Control createDialogArea(Composite parent) { fStatusLabel = new Label(control, SWT.LEFT | SWT.WRAP); fStatusLabel.setLayoutData(new GridData(GridData.FILL, SWT.END, true, false)); + if (fAllowZstd) { + Button useZstdCheckbox = new Button(control, SWT.CHECK); + useZstdCheckbox.setText("Use Zstd Compression"); //$NON-NLS-1$ + zstdCompression = PreferenceUtils.isZstdDefaultCompression(); + useZstdCheckbox.setSelection(zstdCompression); + useZstdCheckbox.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + zstdCompression = useZstdCheckbox.getSelection(); + } + + }); + } applyDialogFont(control); return control; } @@ -168,12 +190,16 @@ protected DialogAction(String text, StructuredViewer viewer, boolean useFilter) super(text, viewer); } - protected File[] openDialog(String text, File path, boolean multiSelection, boolean showFiles) { - FileDialog dialog = new FileDialog(text); + protected File[] openDialog(String text, File path, boolean multiSelection, boolean showFiles, boolean allowZstd) { + FileDialog dialog = new FileDialog(text, allowZstd); dialog.setMultiSelection(multiSelection); dialog.setShowFiles(showFiles); dialog.setSelection(path); int result = dialog.open(); return result == Window.OK ? dialog.getFiles() : null; } + + public boolean isZstdCompression() { + return zstdCompression; + } } diff --git a/ZipEditor/src/zipeditor/actions/ExtractAction.java b/ZipEditor/src/zipeditor/actions/ExtractAction.java index f1c7e28..da5e4fd 100644 --- a/ZipEditor/src/zipeditor/actions/ExtractAction.java +++ b/ZipEditor/src/zipeditor/actions/ExtractAction.java @@ -45,7 +45,7 @@ public void run() { Node[] nodes = getSelectedNodes(); if (nodes.length == 0) nodes = new Node[] { getViewerInputAsNode() }; - File[] folder = openDialog(ActionMessages.getString("ExtractAction.2"), fSelectedFolder, false, false); //$NON-NLS-1$ + File[] folder = openDialog(ActionMessages.getString("ExtractAction.2"), fSelectedFolder, false, false, false); //$NON-NLS-1$ if (folder != null && folder.length > 0) { ExtractOperation operation = new ExtractOperation(); operation.setRefreshJob(new RefreshJob()); diff --git a/ZipEditor/src/zipeditor/messages.properties b/ZipEditor/src/zipeditor/messages.properties index d403135..9e804b2 100644 --- a/ZipEditor/src/zipeditor/messages.properties +++ b/ZipEditor/src/zipeditor/messages.properties @@ -5,6 +5,8 @@ ZipEditor.11=Refreshing Zip editor ZipEditor.12=An error has occurred while trying to save {0} ZipEditor.13=Close ZipEditor.14=Save +ZipEditor.15=The content of this Zip file seems to be invalid.\n\nIt could be that Zstd support is disabled or the Zstd implementation libraries are not available.\nPlease check the Zip Editor preferences. +ZipEditor.16=Open Preference Page ZipEditor.2=Saving ZipEditor.3=Computing number of archive entries ZipEditor.4=File changed @@ -67,3 +69,4 @@ TarNodePropertyPage.1=Invalid user id, must be an Integer TarNodePropertyPage.2=Invalid mode MappingPropertyAccessor.0=Stored MappingPropertyAccessor.8=Deflated +MappingPropertyAccessor.93=Zstd diff --git a/ZipEditor/src/zipeditor/model/Node.java b/ZipEditor/src/zipeditor/model/Node.java index 9b7df2e..2b294e4 100644 --- a/ZipEditor/src/zipeditor/model/Node.java +++ b/ZipEditor/src/zipeditor/model/Node.java @@ -14,6 +14,7 @@ import java.util.Iterator; import java.util.List; +import org.apache.commons.compress.archivers.zip.ZipMethod; import org.apache.commons.io.IOUtils; import org.apache.commons.io.output.NullOutputStream; import org.eclipse.core.runtime.IProgressMonitor; @@ -283,8 +284,11 @@ public void add(Node node, Node beforeSibling) { internalAdd(node, children != null && beforeSibling != null ? children.indexOf(beforeSibling) : -1); } - public void add(File file, Node beforeSibling, IProgressMonitor monitor) { + public void add(File file, Node beforeSibling, IProgressMonitor monitor, boolean useZstdCompression) { Node node = create(model, file.getName(), file.isDirectory()); + if (useZstdCompression && node instanceof ZipNode) { + ((ZipNode)node).setMethod(ZipMethod.ZSTD.getCode()); + } add(node, beforeSibling); node.state |= ADDED; if (node.isFolder()) { @@ -295,7 +299,7 @@ public void add(File file, Node beforeSibling, IProgressMonitor monitor) { if (monitor.isCanceled()) break; monitor.subTask(files[i].getName()); - node.add(files[i], null, monitor); + node.add(files[i], null, monitor, useZstdCompression); } } node.state |= MODIFIED; diff --git a/ZipEditor/src/zipeditor/model/NodeProperty.java b/ZipEditor/src/zipeditor/model/NodeProperty.java index 53b7041..36f7609 100644 --- a/ZipEditor/src/zipeditor/model/NodeProperty.java +++ b/ZipEditor/src/zipeditor/model/NodeProperty.java @@ -14,12 +14,14 @@ public class NodeProperty { public static final int SIZE = 4; public static final int PATH = 9; public static final int PERSISTED = 12; + public static final int METHOD = 13; public static final NodeProperty PNAME = new NodeProperty(NAME); public static final NodeProperty PTYPE = new NodeProperty(TYPE); public static final NodeProperty PDATE = new NodeProperty(DATE); public static final NodeProperty PSIZE = new NodeProperty(SIZE); public static final NodeProperty PPATH = new NodeProperty(PATH); public static final NodeProperty PPERSISTED = new NodeProperty(PERSISTED); + public static final NodeProperty PMETHOD = new NodeProperty(METHOD); protected int type; protected NodeProperty(int type) { diff --git a/ZipEditor/src/zipeditor/model/ZipContentDescriber.java b/ZipEditor/src/zipeditor/model/ZipContentDescriber.java index 261284f..431018d 100644 --- a/ZipEditor/src/zipeditor/model/ZipContentDescriber.java +++ b/ZipEditor/src/zipeditor/model/ZipContentDescriber.java @@ -39,6 +39,8 @@ public static class ContentTypeId { public final static ContentTypeId BZ2_FILE = add("bz2file", ContentTypeId.BZ2); //$NON-NLS-1$ public final static ContentTypeId TBZ_FILE = add("tarbz2file", ContentTypeId.TBZ); //$NON-NLS-1$ public final static ContentTypeId RPM_FILE = add("rpmfile", ContentTypeId.RPM); //$NON-NLS-1$ + // Avoid handling as file, due this is a dummy for invalid file contents. + public final static ContentTypeId INVALID = new ContentTypeId("invalid", -1); // $NON-NLS-1$ private static void init() {} diff --git a/ZipEditor/src/zipeditor/model/ZipEditorZstdException.java b/ZipEditor/src/zipeditor/model/ZipEditorZstdException.java new file mode 100644 index 0000000..2fd0018 --- /dev/null +++ b/ZipEditor/src/zipeditor/model/ZipEditorZstdException.java @@ -0,0 +1,20 @@ +package zipeditor.model; + +import java.io.IOException; + +/** + * This is just a marker class to differ all other {@link IOException}s from the + * Zstd problems. If this exception is thrown, than either the zstd support is + * not activated or the selected zstd compression library is not available. If + * this exception is thrown the zip editor should warn, that this zip file + * contains zstd compression which can't be opened. + */ +public class ZipEditorZstdException extends IOException { + + public ZipEditorZstdException(String message) { + super(message); + } + + private static final long serialVersionUID = 8897411573370620194L; + +} diff --git a/ZipEditor/src/zipeditor/model/ZipModel.java b/ZipEditor/src/zipeditor/model/ZipModel.java index 51a5da4..4925edc 100644 --- a/ZipEditor/src/zipeditor/model/ZipModel.java +++ b/ZipEditor/src/zipeditor/model/ZipModel.java @@ -18,12 +18,12 @@ import java.util.zip.CRC32; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; -import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream; import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream; +import org.apache.commons.compress.archivers.zip.ZipMethod; import org.apache.tools.bzip2.CBZip2InputStream; import org.apache.tools.bzip2.CBZip2OutputStream; import org.apache.tools.tar.TarConstants; @@ -37,12 +37,14 @@ import org.eclipse.core.runtime.ListenerList; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.ui.statushandlers.StatusManager; import zipeditor.Messages; import zipeditor.Utils; import zipeditor.ZipEditorPlugin; import zipeditor.model.IModelListener.ModelChangeEvent; import zipeditor.model.ZipContentDescriber.ContentTypeId; +import zipeditor.model.zstd.ZstdUtilities; import zipeditor.rpm.RpmEntry; import zipeditor.rpm.RpmInputStream; @@ -105,13 +107,18 @@ public static ContentTypeId detectType(InputStream contents) { if (count == -1) return null; try { - ZipArchiveInputStream zip = new ZipArchiveInputStream(contents); + ZipArchiveInputStream zip = new ZstdAwareZipArchiveInputStream(contents); if (zip.getNextEntry() != null) { contents.reset(); return ContentTypeId.ZIP_FILE; } } catch (IOException ioe) { - // thrown in getNextEntry() method if, if file is not a zip file. + if (ioe instanceof ZipEditorZstdException) { + // thrown if zstd support is not active or library is missing + // we can close further actions with this zip file. + return ContentTypeId.INVALID; + } + // thrown in getNextEntry() method, if file is not a zip file. } contents.reset(); try { @@ -257,9 +264,15 @@ private void initialize(InputStream inputStream, IModelInitParticipant participa InputStream zipStream = inputStream; try { zipStream = detectStream(inputStream); + if (ContentTypeId.INVALID == type) { + return; + } root = getRoot(zipStream); readStream(zipStream, participant, stopNode); } catch (IOException e) { + if (e instanceof ZipEditorZstdException) { + type = ContentTypeId.INVALID; + } // ignore } finally { if (zipStream != null && participant == null) { @@ -308,6 +321,11 @@ else if (zipStream instanceof TarInputStream) else if (zipStream instanceof RpmInputStream) rpmEntry = ((RpmInputStream) zipStream).getNextEntry(); } catch (Exception e) { + if (e instanceof ZipEditorZstdException) { + type = ContentTypeId.INVALID; + // No log no error dialog necessary.. Editor will deactivate itself with a hint. + return; + } String message = "Error reading archive"; //$NON-NLS-1$ if (zipPath != null) message += " " + zipPath.getAbsolutePath(); //$NON-NLS-1$ @@ -434,7 +452,7 @@ private InputStream detectStream(InputStream contents) throws IOException { default: return in; case ContentTypeId.ZIP: - return new ZipArchiveInputStream(in); + return new ZstdAwareZipArchiveInputStream(in); case ContentTypeId.TAR: return new TarInputStream(in); case ContentTypeId.GZ: @@ -512,7 +530,7 @@ private void saveNode(OutputStream out, Node node, ContentTypeId type, IProgress monitor.subTask(entryName); zipEntry.setComment(((ZipNode) node).getComment()); zipEntry.setMethod(((ZipNode) node).getMethod()); - if (zipEntry.getMethod() == ZipEntry.STORED) { + if (zipEntry.getMethod() == ZipMethod.STORED.getCode() || zipEntry.getMethod() == ZipMethod.ZSTD.getCode() || zipEntry.getMethod() == ZipMethod.ZSTD_DEPRECATED.getCode()) { handleCrc(node, entryName, zipEntry); } } @@ -535,10 +553,17 @@ private void saveNode(OutputStream out, Node node, ContentTypeId type, IProgress ((ZipArchiveOutputStream) out).putArchiveEntry(zipEntry); else if (out instanceof TarOutputStream) ((TarOutputStream) out).putNextEntry(tarEntry); - Utils.readAndWrite(node.getContent(), out, false); + if (node instanceof ZipNode && ((ZipNode)node).getMethod() == ZipMethod.ZSTD.getCode()) { + try (OutputStream zstdOutput = ZstdUtilities.getOutputStream(out)) { + Utils.readAndWrite(node.getContent(), zstdOutput, false); + zstdOutput.flush(); + } + } else { + Utils.readAndWrite(node.getContent(), out, false); + } if (zipEntry != null) { ((ZipArchiveOutputStream)out).closeArchiveEntry(); - } + } if (tarEntry != null) ((TarOutputStream) out).closeEntry(); monitor.worked(1); diff --git a/ZipEditor/src/zipeditor/model/ZipNode.java b/ZipEditor/src/zipeditor/model/ZipNode.java index 1b263ed..bec1b0b 100644 --- a/ZipEditor/src/zipeditor/model/ZipNode.java +++ b/ZipEditor/src/zipeditor/model/ZipNode.java @@ -5,6 +5,8 @@ package zipeditor.model; import org.apache.commons.compress.archivers.zip.ZipFile; +import org.apache.commons.compress.archivers.zip.ZipMethod; +import zipeditor.model.zstd.ZstdUtilities; import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; import java.io.IOException; import java.io.InputStream; @@ -82,14 +84,25 @@ public void setMethod(int method) { protected InputStream doGetContent() throws IOException { InputStream in = super.doGetContent(); - if (in != null) + if (in != null) { return in; - if (zipEntry != null) { - return model.getZipPath() != null ? new EntryStream(zipEntry, ZipFile.builder().setFile(model.getZipPath()).get()) : null; + } + if (zipEntry != null && model.getZipPath() != null) { + ZipFile zipFile; + if (isZstdEncoded(zipEntry)) { + zipFile = ZstdUtilities.getZipFileBuilder().setFile(model.getZipPath()).get(); + } else { + zipFile = ZipFile.builder().setFile(model.getZipPath()).get(); + } + return new EntryStream(zipEntry, zipFile); } return null; } + private static boolean isZstdEncoded(ZipArchiveEntry zipEntry) { + return zipEntry.getMethod() == ZipMethod.ZSTD.getCode() || zipEntry.getMethod() == ZipMethod.ZSTD_DEPRECATED.getCode(); + } + public void reset() { super.reset(); if (zipEntry != null) { diff --git a/ZipEditor/src/zipeditor/model/ZipRootNode.java b/ZipEditor/src/zipeditor/model/ZipRootNode.java index a4d25ab..85cec50 100644 --- a/ZipEditor/src/zipeditor/model/ZipRootNode.java +++ b/ZipEditor/src/zipeditor/model/ZipRootNode.java @@ -13,4 +13,29 @@ public ZipRootNode(ZipModel model) { public Node create(ZipModel model, String name, boolean isFolder) { return new ZipNode(model, name, isFolder); } + + /** + * This method can be used to check if new compression methods can be used without doubts. + * + * @param zipMethod the compression method to check + * @return true if the given zipMethod was already used in this node model, else false. + */ + public boolean hasContentWithCompression(int zipMethod) { + return hasContentWithCompression(this, zipMethod); + } + + private boolean hasContentWithCompression(Node parentNode, int zipMethod) { + for (Node node : parentNode.getChildren()) { + if (!(node instanceof ZipNode zipNode)) { + continue; + } + if (zipNode.getMethod() == zipMethod) { + return true; + } + if (hasContentWithCompression(zipNode, zipMethod)) { + return true; + } + } + return false; + } } diff --git a/ZipEditor/src/zipeditor/model/ZstdAwareZipArchiveInputStream.java b/ZipEditor/src/zipeditor/model/ZstdAwareZipArchiveInputStream.java new file mode 100644 index 0000000..13a223d --- /dev/null +++ b/ZipEditor/src/zipeditor/model/ZstdAwareZipArchiveInputStream.java @@ -0,0 +1,20 @@ +package zipeditor.model; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; + +import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream; + +import zipeditor.model.zstd.ZstdUtilities; + +public final class ZstdAwareZipArchiveInputStream extends ZipArchiveInputStream { + public ZstdAwareZipArchiveInputStream(InputStream inputStream) { + super(inputStream, StandardCharsets.UTF_8.name(), true, true); + } + + @Override + protected InputStream createZstdInputStream(InputStream in) throws IOException { + return ZstdUtilities.getInputStream(in); + } +} \ No newline at end of file diff --git a/ZipEditor/src/zipeditor/model/zstd/AircompressorHandler.java b/ZipEditor/src/zipeditor/model/zstd/AircompressorHandler.java new file mode 100644 index 0000000..e740cc8 --- /dev/null +++ b/ZipEditor/src/zipeditor/model/zstd/AircompressorHandler.java @@ -0,0 +1,28 @@ +package zipeditor.model.zstd; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import org.apache.commons.io.function.IOFunction; + +import io.airlift.compress.zstd.ZstdInputStream; +import io.airlift.compress.zstd.ZstdOutputStream; + +public class AircompressorHandler implements ZstdImplementationHandler { + + @Override + public InputStream createInputStream(InputStream input) { + return new ZstdInputStream(input); + } + + @Override + public OutputStream createOutputStream(OutputStream output) throws IOException { + return new ZstdOutputStream(noClose(output)); + } + + @Override + public IOFunction getIOFunction() { + return ZstdInputStream::new; + } +} diff --git a/ZipEditor/src/zipeditor/model/zstd/JniZstdLibCompressorHandler.java b/ZipEditor/src/zipeditor/model/zstd/JniZstdLibCompressorHandler.java new file mode 100644 index 0000000..879c617 --- /dev/null +++ b/ZipEditor/src/zipeditor/model/zstd/JniZstdLibCompressorHandler.java @@ -0,0 +1,29 @@ +package zipeditor.model.zstd; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import org.apache.commons.compress.compressors.zstandard.ZstdCompressorInputStream; +import org.apache.commons.compress.compressors.zstandard.ZstdCompressorOutputStream; +import org.apache.commons.io.function.IOFunction; + +import zipeditor.preferences.PreferenceUtils; + +public class JniZstdLibCompressorHandler implements ZstdImplementationHandler { + + @Override + public InputStream createInputStream(InputStream input) throws IOException { + return new ZstdCompressorInputStream(input); + } + + @Override + public OutputStream createOutputStream(OutputStream output) throws IOException { + return new ZstdCompressorOutputStream(noClose(output), PreferenceUtils.getCompressionLevel()); + } + + @Override + public IOFunction getIOFunction() { + return ZstdCompressorInputStream::new; + } +} diff --git a/ZipEditor/src/zipeditor/model/zstd/Messages.java b/ZipEditor/src/zipeditor/model/zstd/Messages.java new file mode 100644 index 0000000..dd309e0 --- /dev/null +++ b/ZipEditor/src/zipeditor/model/zstd/Messages.java @@ -0,0 +1,18 @@ +package zipeditor.model.zstd; + +import org.eclipse.osgi.util.NLS; + +public class Messages extends NLS { + private static final String BUNDLE_NAME = Messages.class.getPackageName() + ".messages"; //$NON-NLS-1$ + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } + + public static String ZstdHandler_aircompLibNotAvailable; + public static String ZstdHandler_jniLibNotAvailable; + public static String ZstdHandler_notActive; +} diff --git a/ZipEditor/src/zipeditor/model/zstd/ZstdImplementationHandler.java b/ZipEditor/src/zipeditor/model/zstd/ZstdImplementationHandler.java new file mode 100644 index 0000000..2f27bd3 --- /dev/null +++ b/ZipEditor/src/zipeditor/model/zstd/ZstdImplementationHandler.java @@ -0,0 +1,36 @@ +package zipeditor.model.zstd; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import org.apache.commons.io.function.IOFunction; + +public interface ZstdImplementationHandler { + + default OutputStream noClose(OutputStream out) { + return new OutputStream() { + @Override + public void write(byte[] b) throws IOException { + out.write(b); + } + + @Override + public void write(int b) throws IOException { + out.write(b); + } + + @Override + public void write(byte[] b, int off, int len) throws IOException { + out.write(b, off, len); + } + }; + } + + InputStream createInputStream(InputStream input) throws IOException; + + OutputStream createOutputStream(OutputStream output) throws IOException; + + IOFunction getIOFunction(); + +} diff --git a/ZipEditor/src/zipeditor/model/zstd/ZstdUtilities.java b/ZipEditor/src/zipeditor/model/zstd/ZstdUtilities.java new file mode 100644 index 0000000..18719aa --- /dev/null +++ b/ZipEditor/src/zipeditor/model/zstd/ZstdUtilities.java @@ -0,0 +1,83 @@ +package zipeditor.model.zstd; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import org.apache.commons.compress.archivers.zip.ZipFile; +import org.apache.commons.compress.archivers.zip.ZipMethod; +import org.apache.commons.compress.archivers.zip.ZipFile.Builder; +import org.apache.commons.compress.compressors.zstandard.ZstdUtils; + +import zipeditor.model.Node; +import zipeditor.model.RootNode; +import zipeditor.model.ZipEditorZstdException; +import zipeditor.model.ZipRootNode; +import zipeditor.preferences.PreferenceUtils; + +public class ZstdUtilities { + + public static InputStream getInputStream(InputStream in) throws IOException { + if (!PreferenceUtils.isZstdAvailableAndActive()) { + throw new ZipEditorZstdException(Messages.ZstdHandler_notActive); + } + String library = PreferenceUtils.getSelectedOrAvailableLibrary(); + if (PreferenceUtils.JNI_LIBRARY.equals(library)) { + return new JniZstdLibCompressorHandler().createInputStream(in); + } else { + return new AircompressorHandler().createInputStream(in); + } + } + + public static OutputStream getOutputStream(OutputStream out) throws IOException { + if (!PreferenceUtils.isZstdAvailableAndActive()) { + throw new ZipEditorZstdException(Messages.ZstdHandler_notActive); + } + String library = PreferenceUtils.getSelectedOrAvailableLibrary(); + if (PreferenceUtils.JNI_LIBRARY.equals(library)) { + return new JniZstdLibCompressorHandler().createOutputStream(out); + } else { + return new AircompressorHandler().createOutputStream(out); + } + } + + private static boolean hasAircompressor; + private static boolean checked; + public static boolean isAircompressorAvailable() { + if (checked) + return hasAircompressor; + + checked = true; + try { + Class.forName("io.airlift.compress.zstd.ZstdInputStream"); //$NON-NLS-1$ + hasAircompressor = true; + } catch (ClassNotFoundException e) { + hasAircompressor = false; + } + return hasAircompressor; + } + + public static Builder getZipFileBuilder() throws ZipEditorZstdException { + if (!PreferenceUtils.isZstdAvailableAndActive()) { + throw new ZipEditorZstdException(Messages.ZstdHandler_notActive); + } + String library = PreferenceUtils.getSelectedOrAvailableLibrary(); + if (PreferenceUtils.JNI_LIBRARY.equals(library)) { + return ZipFile.builder(); + } else { + return ZipFile.builder().setZstdInputStreamFactory(new AircompressorHandler().getIOFunction()); + } + } + + public static boolean isZstdJniCompressionAvailable() { + return ZstdUtils.isZstdCompressionAvailable(); + } + + public static boolean useZstdCompression(Node parentNode) { + boolean useZstdCompression = PreferenceUtils.isZstdAvailableAndActive() && PreferenceUtils.isZstdDefaultCompression(); + RootNode root = parentNode.getModel().getRoot(); + if (useZstdCompression && root instanceof ZipRootNode zipRootNode) { + useZstdCompression = zipRootNode.getChildren().length == 0 || zipRootNode.hasContentWithCompression(ZipMethod.ZSTD.getCode()); + } + return useZstdCompression; + } +} diff --git a/ZipEditor/src/zipeditor/model/zstd/messages.properties b/ZipEditor/src/zipeditor/model/zstd/messages.properties new file mode 100644 index 0000000..8206a1d --- /dev/null +++ b/ZipEditor/src/zipeditor/model/zstd/messages.properties @@ -0,0 +1,3 @@ +ZstdHandler_aircompLibNotAvailable=Aircompressor is selected but not available +ZstdHandler_jniLibNotAvailable=zstd-jni library is not available +ZstdHandler_notActive=Support for zstd is deactivated or there is no available zstd library. Please check the zip editor settings. diff --git a/ZipEditor/src/zipeditor/operations/AddOperation.java b/ZipEditor/src/zipeditor/operations/AddOperation.java index c197114..59fb918 100644 --- a/ZipEditor/src/zipeditor/operations/AddOperation.java +++ b/ZipEditor/src/zipeditor/operations/AddOperation.java @@ -25,13 +25,15 @@ private class AddFilesJob extends Job { private Node fParentNode; private Node fBeforeSibling; private UIJob fRefreshJob; + private boolean fUseZstdCompression; - public AddFilesJob(File[] filesNames, Node parentNode, Node beforeSibling, UIJob refreshJob) { + public AddFilesJob(File[] filesNames, Node parentNode, Node beforeSibling, UIJob refreshJob, boolean useZstdCompression) { super(Messages.getString("AddOperation.1")); //$NON-NLS-1$ fFilesNames = filesNames; fParentNode = parentNode; fBeforeSibling = beforeSibling; fRefreshJob = refreshJob; + fUseZstdCompression = useZstdCompression; } public IStatus run(IProgressMonitor monitor) { @@ -47,7 +49,7 @@ public IStatus run(IProgressMonitor monitor) { if (subMonitor.isCanceled()) break; try { - fParentNode.add(fFilesNames[i], fBeforeSibling, subMonitor); + fParentNode.add(fFilesNames[i], fBeforeSibling, subMonitor, fUseZstdCompression); oneAdded = true; } catch (Exception e) { return ZipEditorPlugin.createErrorStatus(Messages.getString("AddOperation.0"), e); //$NON-NLS-1$ @@ -82,18 +84,22 @@ public IStatus runInUIThread(IProgressMonitor monitor) { }; public void execute(String[] fileNames, Node parentNode, Node beforeSibling, StructuredViewer viewer) { - execute(getFilesFromNames(fileNames), parentNode, beforeSibling, viewer); + // The default case is disabled zstd compressoin. This is done to not disturb all other cases. + execute(fileNames, parentNode, beforeSibling, viewer, false); } - public void execute(File[] fileNames, Node parentNode, Node beforeSibling, StructuredViewer viewer) { - + public void execute(String[] fileNames, Node parentNode, Node beforeSibling, StructuredViewer viewer, boolean useZstdCompression) { + execute(getFilesFromNames(fileNames), parentNode, beforeSibling, viewer, useZstdCompression); + } + + public void execute(File[] fileNames, Node parentNode, Node beforeSibling, StructuredViewer viewer, boolean useZstdCompression) { while (parentNode != null && !parentNode.isFolder()) parentNode = parentNode.getParent(); - AddFilesJob addFilesJob = new AddFilesJob(fileNames, parentNode, beforeSibling, new RefreshJob(viewer)); + AddFilesJob addFilesJob = new AddFilesJob(fileNames, parentNode, beforeSibling, new RefreshJob(viewer), useZstdCompression); addFilesJob.schedule(); } - private File[] getFilesFromNames(String[] filesNames) { + public File[] getFilesFromNames(String[] filesNames) { File[] files = new File[filesNames.length]; for (int i = 0; i < files.length; i++) { files[i] = new File(filesNames[i]); diff --git a/ZipEditor/src/zipeditor/operations/ExtractOperation.java b/ZipEditor/src/zipeditor/operations/ExtractOperation.java index c2a4e82..9c15fc1 100644 --- a/ZipEditor/src/zipeditor/operations/ExtractOperation.java +++ b/ZipEditor/src/zipeditor/operations/ExtractOperation.java @@ -9,6 +9,7 @@ import java.util.HashSet; import java.util.Set; +import org.apache.commons.io.IOUtils; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; @@ -172,7 +173,9 @@ private File internalExtract(Node node, File toDir, boolean overwrite, boolean f try { extracting.add(file); long time = System.currentTimeMillis(); - Utils.readAndWrite(node.getContent(), new FileOutputStream(file), true); + try (FileOutputStream out = new FileOutputStream(file)) { + IOUtils.copyLarge(node.getContent(), out); + } if (ZipEditorPlugin.DEBUG) System.out.println("Extracted " + node + " in " + (System.currentTimeMillis() - time) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } catch (Exception e) { diff --git a/ZipEditor/src/zipeditor/preferences/Messages.java b/ZipEditor/src/zipeditor/preferences/Messages.java new file mode 100644 index 0000000..5f68f08 --- /dev/null +++ b/ZipEditor/src/zipeditor/preferences/Messages.java @@ -0,0 +1,26 @@ +package zipeditor.preferences; + +import org.eclipse.osgi.util.NLS; + +public class Messages extends NLS { + private static final String BUNDLE_NAME = Messages.class.getPackageName() + ".messages"; //$NON-NLS-1$ + public static String PreferenceUtils_AircompressorLabel; + public static String PreferenceUtils_ZSTDJniLibraryLabel; + public static String ZipEditorPreferencePage_LibAvailable; + public static String ZipEditorPreferencePage_LibNotAvailable; + public static String ZipEditorPreferencePage_ZstdAsDefaultCompression; + public static String ZipEditorPreferencePage_ZstdCompressionLevel; + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } + + public static String ZipEditorPreferencePage_ActivateZstdSupport; + public static String ZipEditorPreferencePage_HintNoLibraries; + public static String ZipEditorPreferencePage_ScaleValueCompressionLevel; + public static String ZipEditorPreferencePage_ZstdLibrary; + public static String ZipEditorPreferencePage_ZstdSettingsGroupTitle; +} diff --git a/ZipEditor/src/zipeditor/preferences/PreferenceUtils.java b/ZipEditor/src/zipeditor/preferences/PreferenceUtils.java new file mode 100644 index 0000000..3a59c29 --- /dev/null +++ b/ZipEditor/src/zipeditor/preferences/PreferenceUtils.java @@ -0,0 +1,150 @@ +package zipeditor.preferences; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.preference.IPreferenceStore; + +import zipeditor.PreferenceConstants; +import zipeditor.ZipEditorPlugin; +import zipeditor.model.zstd.ZstdUtilities; + +public class PreferenceUtils { + + public record ZstdLibrary(String label, String identifier) { + public ZstdLibrary(String label, String identifier) { + this.label = label; + this.identifier = identifier; + } + } + /** + * Preference value for the aircompressor library. + */ + public static final String AIRCOMPRESSOR = "aircompressor"; //$NON-NLS-1$ + + /** + * Preference value for the zstd-jni library. + */ + public static final String JNI_LIBRARY = "jniLibrary"; //$NON-NLS-1$ + + public static final List libraries = new ArrayList(); + static { + libraries.add(new ZstdLibrary(Messages.PreferenceUtils_ZSTDJniLibraryLabel, JNI_LIBRARY)); + libraries.add(new ZstdLibrary(Messages.PreferenceUtils_AircompressorLabel, AIRCOMPRESSOR)); + } + + private static String getSelectedZstdLib() { + IPreferenceStore preferenceStore = ZipEditorPlugin.getDefault().getPreferenceStore(); + String selectedLib = preferenceStore + .getString(PreferenceConstants.PREFIX_EDITOR + PreferenceConstants.SELECTED_ZSTD_LIB); + return selectedLib; + } + + /** + * Returns the available libraries. + * @return a {@link List} of available {@link ZstdLibrary} objects. + */ + public static List getAvailableLibraries() { + List availableLibs = new ArrayList(); + for (ZstdLibrary libData : libraries) { + if (libData.identifier.equals(JNI_LIBRARY) && ZstdUtilities.isZstdJniCompressionAvailable()) { + availableLibs.add(libData); + } else if (libData.identifier.equals(AIRCOMPRESSOR) && ZstdUtilities.isAircompressorAvailable()) { + availableLibs.add(libData); + } + } + return availableLibs; + } + + /** + * Returns the available libraries. + * @return a {@link List} of available {@link ZstdLibrary} objects. + */ + public static String[][] getAvailableLibrariesForPreferenceUI() { + List availableLibraries = getAvailableLibraries(); + String[][] libs = new String[availableLibraries.size()][2]; + for (int i = 0; i < availableLibraries.size(); i++) { + ZstdLibrary zstdLibrary = availableLibraries.get(i); + libs[i] = new String[] { zstdLibrary.label, zstdLibrary.identifier }; + } + return libs; + } + + /** + * @return true, if the zstd handling is active. + */ + static boolean isZstdActive() { + IPreferenceStore preferenceStore = ZipEditorPlugin.getDefault().getPreferenceStore(); + return preferenceStore.getBoolean(PreferenceConstants.PREFIX_EDITOR + PreferenceConstants.ACTIVATE_ZSTD_LIB); + } + + /** + * @return true, if the zstd-jni library is selected for zstd handling. + */ + public static boolean isJNIZstdSelected() { + String selectedLib = getSelectedZstdLib(); + + return JNI_LIBRARY.equals(selectedLib); + } + + /** + * @return true, if the aircompressor library is selected for zstd handling. + */ + public static boolean isAircompressorSelected() { + String selectedLib = getSelectedZstdLib(); + + return AIRCOMPRESSOR.equals(selectedLib); + } + + /** + * Checks if any zstd library is available and the zstd active pref is true. + * + * @return + */ + public static boolean isZstdAvailableAndActive() { + return isZstdActive() && getAvailableLibraries().size() > 0; + } + + /** + * Returns the preference value for default zstd compression + * + * @return true if zstd can be used as default or it returns false. + */ + public static boolean isZstdDefaultCompression() { + IPreferenceStore preferenceStore = ZipEditorPlugin.getDefault().getPreferenceStore(); + return preferenceStore.getBoolean(PreferenceConstants.PREFIX_EDITOR + PreferenceConstants.USE_ZSTD_AS_DEFAULT); + } + + /** + * Returns the preference value for the zstd compression level. + * + * @return the value of the compression level preference. + */ + public static int getCompressionLevel() { + IPreferenceStore preferenceStore = ZipEditorPlugin.getDefault().getPreferenceStore(); + return preferenceStore.getInt(PreferenceConstants.PREFIX_EDITOR + PreferenceConstants.COMPRESSION_LEVEL); + } + + /** + * Checks if the selected library is available and returns it. + * If the selected library is not available it returns the available one. + * + * @return the selected or available library. + * identifier of the library which is written in the constants JNI_LIBRARY or AIRCOMPRESSOR + * or null if there is no library available. + */ + public static String getSelectedOrAvailableLibrary() { + List availableLibraries = getAvailableLibraries(); + if (availableLibraries.size() == 0) { + return null; + } + String selectedZstdLibIdentifier = getSelectedZstdLib(); + for (ZstdLibrary library : availableLibraries) { + if (selectedZstdLibIdentifier.equals(library.identifier)) { + return selectedZstdLibIdentifier; + } + } + + return availableLibraries.get(0).identifier; + } +} diff --git a/ZipEditor/src/zipeditor/preferences/ZipEditorPreferencePage.java b/ZipEditor/src/zipeditor/preferences/ZipEditorPreferencePage.java new file mode 100644 index 0000000..cc9ddeb --- /dev/null +++ b/ZipEditor/src/zipeditor/preferences/ZipEditorPreferencePage.java @@ -0,0 +1,161 @@ +package zipeditor.preferences; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.preference.*; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.IWorkbenchPreferencePage; +import org.eclipse.ui.IWorkbench; +import zipeditor.PreferenceConstants; +import zipeditor.ZipEditorPlugin; + +/** + * This is the Preference Page for changing the zstd library for reading / writing a zstd compressed stream. + * The zstd libraries are optional so the zstd handling can also be disabled, which will lead to loose of the zstd compressed data, after saving. + */ +public class ZipEditorPreferencePage + extends FieldEditorPreferencePage + implements IWorkbenchPreferencePage, IPropertyChangeListener { + + private ComboFieldEditor zstdLibComboFieldEditor; + private BooleanFieldEditor zstdStateFieldEditor; + private BooleanFieldEditor fBooleanFieldEditor; + private ScaleFieldEditor zstdCompressionLevelFieldEditor; + private Label fLScaleValue; + + public ZipEditorPreferencePage() { + super(GRID); + setPreferenceStore(ZipEditorPlugin.getDefault().getPreferenceStore()); + } + + public void createFieldEditors() { + String[][] availableLibraries = PreferenceUtils.getAvailableLibrariesForPreferenceUI(); + if (availableLibraries.length >= 1) { + zstdStateFieldEditor = new BooleanFieldEditor( + PreferenceConstants.PREFIX_EDITOR + PreferenceConstants.ACTIVATE_ZSTD_LIB, + Messages.ZipEditorPreferencePage_ActivateZstdSupport, + getFieldEditorParent()); + addField(zstdStateFieldEditor); + + if (availableLibraries.length == 1) { + Label lLibraryName = new Label(getFieldEditorParent(), SWT.NONE); + GridDataFactory.fillDefaults().span(2, 1).applyTo(lLibraryName); + lLibraryName.setText(Messages.ZipEditorPreferencePage_ZstdLibrary + ' ' + availableLibraries[0][0]); + + + if (PreferenceUtils.JNI_LIBRARY.equals(availableLibraries[0][1])) { + addZstdCompressionLevelField(); + } + } else { + String selectedZstdLibPrefName = PreferenceConstants.PREFIX_EDITOR + PreferenceConstants.SELECTED_ZSTD_LIB; + zstdLibComboFieldEditor = new ComboFieldEditor(selectedZstdLibPrefName, Messages.ZipEditorPreferencePage_ZstdLibrary, availableLibraries, getFieldEditorParent()) { + @Override + protected void valueChanged(String oldValue, String newValue) { + super.valueChanged(oldValue, newValue); + + boolean isVisible = PreferenceUtils.JNI_LIBRARY.equals(newValue); + zstdCompressionLevelFieldEditor.getScaleControl().setVisible(isVisible); + zstdCompressionLevelFieldEditor.getLabelControl(getFieldEditorParent()).setVisible(isVisible); + fLScaleValue.setVisible(isVisible); + + zstdCompressionLevelFieldEditor.getScaleControl().setEnabled(isVisible); + zstdCompressionLevelFieldEditor.getLabelControl(getFieldEditorParent()).setEnabled(isVisible); + fLScaleValue.setEnabled(isVisible); + } + }; + addField(zstdLibComboFieldEditor); + zstdLibComboFieldEditor.setEnabled(PreferenceUtils.isZstdActive(), getFieldEditorParent()); + getPreferenceStore().addPropertyChangeListener(this); + + addZstdCompressionLevelField(); + } + + String zstdDefaultPrefName = PreferenceConstants.PREFIX_EDITOR + PreferenceConstants.USE_ZSTD_AS_DEFAULT; + fBooleanFieldEditor = new BooleanFieldEditor(zstdDefaultPrefName, Messages.ZipEditorPreferencePage_ZstdAsDefaultCompression, getFieldEditorParent()); + addField(fBooleanFieldEditor); + fBooleanFieldEditor.setEnabled(PreferenceUtils.isZstdActive(), getFieldEditorParent()); + + } else { + Label lHint = new Label(getFieldEditorParent(), SWT.WRAP); + lHint.setText(Messages.ZipEditorPreferencePage_HintNoLibraries); + GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).grab(false, false).applyTo(lHint); + lHint.pack(true); + } + } + + private void addZstdCompressionLevelField() { + String zstdCompressionLevelPrefName = PreferenceConstants.PREFIX_EDITOR + PreferenceConstants.COMPRESSION_LEVEL; + zstdCompressionLevelFieldEditor = new ScaleFieldEditor(zstdCompressionLevelPrefName, Messages.ZipEditorPreferencePage_ZstdCompressionLevel, getFieldEditorParent()); + addField(zstdCompressionLevelFieldEditor); + zstdCompressionLevelFieldEditor.setMaximum(0); + zstdCompressionLevelFieldEditor.setMaximum(22); + zstdCompressionLevelFieldEditor.setIncrement(1); + fLScaleValue = new Label(getFieldEditorParent(), SWT.WRAP); + GridDataFactory.fillDefaults().span(2, 1).align(SWT.FILL, SWT.FILL).grab(true, false).applyTo(fLScaleValue); + zstdCompressionLevelFieldEditor.getScaleControl().addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + int selection = zstdCompressionLevelFieldEditor.getScaleControl().getSelection(); + fLScaleValue.setText(Messages.ZipEditorPreferencePage_ScaleValueCompressionLevel + selection); + } + }); + + zstdCompressionLevelFieldEditor.load(); + fLScaleValue.setText(Messages.ZipEditorPreferencePage_ScaleValueCompressionLevel + PreferenceUtils.getCompressionLevel()); + + boolean aircompNotSelected = !PreferenceUtils.isAircompressorSelected(); + + zstdCompressionLevelFieldEditor.getScaleControl().setVisible(aircompNotSelected); + zstdCompressionLevelFieldEditor.getLabelControl(getFieldEditorParent()).setVisible(aircompNotSelected); + fLScaleValue.setVisible(aircompNotSelected); + + if (aircompNotSelected) { + boolean isEnabled = PreferenceUtils.isZstdAvailableAndActive(); + + zstdCompressionLevelFieldEditor.getScaleControl().setEnabled(isEnabled); + zstdCompressionLevelFieldEditor.getLabelControl(getFieldEditorParent()).setEnabled(isEnabled); + fLScaleValue.setEnabled(isEnabled); + } + } + + @Override + public void propertyChange(PropertyChangeEvent event) { + super.propertyChange(event); + + if (event.getSource() instanceof BooleanFieldEditor booleanFieldEditor) { + if ((PreferenceConstants.PREFIX_EDITOR + PreferenceConstants.ACTIVATE_ZSTD_LIB).equals(booleanFieldEditor.getPreferenceName())) { + boolean isEnabled = (boolean) event.getNewValue(); + if (zstdLibComboFieldEditor != null) { + zstdLibComboFieldEditor.setEnabled(isEnabled, getFieldEditorParent()); + } + if (zstdCompressionLevelFieldEditor != null) { + zstdCompressionLevelFieldEditor.setEnabled(isEnabled, getFieldEditorParent()); + } + if (fLScaleValue != null) { + fLScaleValue.setEnabled(isEnabled); + } + if (fBooleanFieldEditor != null) { + fBooleanFieldEditor.setEnabled(isEnabled, getFieldEditorParent()); + } + } + } + } + + @Override + public void dispose() { + getPreferenceStore().removePropertyChangeListener(this); + + super.dispose(); + } + + @Override + public void init(IWorkbench workbench) { + // nothing to do.. + } + +} \ No newline at end of file diff --git a/ZipEditor/src/zipeditor/preferences/messages.properties b/ZipEditor/src/zipeditor/preferences/messages.properties new file mode 100644 index 0000000..b64d644 --- /dev/null +++ b/ZipEditor/src/zipeditor/preferences/messages.properties @@ -0,0 +1,11 @@ +PreferenceUtils_AircompressorLabel=Aircompressor +PreferenceUtils_ZSTDJniLibraryLabel=JNI Library +ZipEditorPreferencePage_ActivateZstdSupport=Activate Zstd Support +ZipEditorPreferencePage_HintNoLibraries=Zstd zip compression support is not available.\nIf you want to use zstd compression, you have to install a library that provides zstd compression, like zstd-jni or aircompressor. +ZipEditorPreferencePage_LibAvailable=Library is available +ZipEditorPreferencePage_LibNotAvailable=Library is not available +ZipEditorPreferencePage_ScaleValueCompressionLevel=Selected Compression level: +ZipEditorPreferencePage_ZstdAsDefaultCompression=Use Zstd compression by default for new zip files +ZipEditorPreferencePage_ZstdCompressionLevel=Compression Level: +ZipEditorPreferencePage_ZstdLibrary=Zstd Library: +ZipEditorPreferencePage_ZstdSettingsGroupTitle=Zstd Settings: diff --git a/maven-bnd/README.md b/maven-bnd/README.md new file mode 100644 index 0000000..6660cfa --- /dev/null +++ b/maven-bnd/README.md @@ -0,0 +1,15 @@ +# Maven BND + +## Content + +A [content report](../report/maven-bnd/merged-target/REPORT.md) is generated for the contents of [MavenBND.target](tp/MavenBND.target) with links to the artifacts in Maven Central. + + +## Updates + +Updates are provided by [https://download.eclipse.org/tools/orbit/simrel/maven-bnd](https://download.eclipse.org/tools/orbit/simrel/maven-bnd). + + +## Builds + +Builds are driven by [https://ci.eclipse.org/orbit/job/orbit-simrel-maven-bnd](https://ci.eclipse.org/orbit/job/orbit-simrel-maven-bnd). diff --git a/maven-bnd/pom.xml b/maven-bnd/pom.xml new file mode 100644 index 0000000..b37c6f0 --- /dev/null +++ b/maven-bnd/pom.xml @@ -0,0 +1,147 @@ + + + 4.0.0 + + org.eclipse.orbit.maven-bnd + org.eclipse.orbit.maven-bnd.parent + pom + + + com.github + ../ + 1.0.0-SNAPSHOT + ZipEditor.parent + + + + UTF-8 + 1.5.2 + yyyyMMddHHmm + 1.1.1-SNAPSHOT + + + + + tycho-snapshots + https://repo.eclipse.org/content/repositories/tycho-snapshots + + + + eclipse-maven-releases + https://repo.eclipse.org/content/repositories/releases + + + + eclipse-cbi-releases + https://repo.eclipse.org/content/repositories/cbi-releases + + + maven-repository + https://repo1.maven.org/maven2 + + + apache-repository + https://repository.apache.org/content/repositories/snapshots + + true + + + + + + + + org.eclipse.tycho + tycho-maven-plugin + true + + + org.eclipse.tycho + tycho-p2-publisher-plugin + ${tycho-version} + + true + + + + org.eclipse.tycho + target-platform-configuration + ${tycho-version} + + + + org.eclipse.orbit.maven-bnd + org.eclipse.orbit.maven-bnd.tp + 1.0.0-SNAPSHOT + MavenBND + + + JavaSE-21 + + + win32 + win32 + x86_64 + + + macosx + cocoa + x86_64 + + + macosx + cocoa + aarch64 + + + linux + gtk + x86_64 + + + linux + gtk + aarch64 + + + + + true + + + + + + + + + org.eclipse.tycho + tycho-maven-plugin + ${tycho-version} + true + + + org.eclipse.cbi.maven.plugins + eclipse-jarsigner-plugin + ${jarsigner-version} + + + org.apache.maven.shared + maven-shared-utils + 3.4.2 + + + + + + + + + tp + site + + + \ No newline at end of file diff --git a/maven-bnd/site/.gitignore b/maven-bnd/site/.gitignore new file mode 100644 index 0000000..b83d222 --- /dev/null +++ b/maven-bnd/site/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/maven-bnd/site/.project b/maven-bnd/site/.project new file mode 100644 index 0000000..3a020d4 --- /dev/null +++ b/maven-bnd/site/.project @@ -0,0 +1,17 @@ + + + site + + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.m2e.core.maven2Nature + + diff --git a/maven-bnd/site/category.xml b/maven-bnd/site/category.xml new file mode 100644 index 0000000..afde35c --- /dev/null +++ b/maven-bnd/site/category.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/maven-bnd/site/pom.xml b/maven-bnd/site/pom.xml new file mode 100644 index 0000000..f553cfd --- /dev/null +++ b/maven-bnd/site/pom.xml @@ -0,0 +1,34 @@ + + + 4.0.0 + + org.eclipse.orbit.maven-bnd + org.eclipse.orbit.maven-bnd.parent + 1.0.0-SNAPSHOT + .. + + + org.eclipse.orbit.maven-bnd.site + eclipse-repository + + + + + org.eclipse.tycho + tycho-p2-repository-plugin + ${tycho-version} + + Orbit Maven BND + true + true + false + false + + + + + + diff --git a/maven-bnd/tp/MavenBND.target b/maven-bnd/tp/MavenBND.target new file mode 100644 index 0000000..da61190 --- /dev/null +++ b/maven-bnd/tp/MavenBND.target @@ -0,0 +1,81 @@ + + + + + + + + io.airlift + aircompressor + 2.0.2 + jar + + + + + Id1 + https://repo1.maven.org/maven2/ + + + + + + + + org.apache.commons + commons-compress + 1.28.0-SNAPSHOT + jar + + + org.apache.commons + commons-lang3 + 3.18.0-SNAPSHOT + jar + + + + + apache snapshot + https://repository.apache.org/content/repositories/snapshots/ + + + + + + + + com.github.luben + zstd-jni + 1.5.7-2 + jar + + + + + + \ No newline at end of file diff --git a/maven-bnd/tp/pom.xml b/maven-bnd/tp/pom.xml new file mode 100644 index 0000000..e75e699 --- /dev/null +++ b/maven-bnd/tp/pom.xml @@ -0,0 +1,22 @@ + + + + 4.0.0 + + org.eclipse.orbit.maven-bnd + org.eclipse.orbit.maven-bnd.parent + 1.0.0-SNAPSHOT + .. + + org.eclipse.orbit.maven-bnd.tp + eclipse-target-definition + diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..e55bcd4 --- /dev/null +++ b/pom.xml @@ -0,0 +1,48 @@ + + 4.0.0 + + com.github + ZipEditor.parent + 1.0.0-SNAPSHOT + pom + + + 4.0.13 + + + + maven-bnd + ZipEditor + zipeditor.feature + ZipEditor.targetPlatform + ZipEditor.UpdateSite + + + + + + + org.eclipse.tycho + tycho-maven-plugin + ${tycho-version} + true + + + org.eclipse.cbi.maven.plugins + eclipse-jarsigner-plugin + ${jarsigner-version} + + + org.apache.maven.shared + maven-shared-utils + 3.4.2 + + + + + + + \ No newline at end of file diff --git a/zipeditor.feature/.gitignore b/zipeditor.feature/.gitignore new file mode 100644 index 0000000..b83d222 --- /dev/null +++ b/zipeditor.feature/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/ZipEditor Feature/.project b/zipeditor.feature/.project similarity index 91% rename from ZipEditor Feature/.project rename to zipeditor.feature/.project index 057f33a..5bbd900 100644 --- a/ZipEditor Feature/.project +++ b/zipeditor.feature/.project @@ -1,6 +1,6 @@ - ZipEditor Feature + zipeditor.feature diff --git a/ZipEditor Feature/.settings/org.eclipse.core.resources.prefs b/zipeditor.feature/.settings/org.eclipse.core.resources.prefs similarity index 50% rename from ZipEditor Feature/.settings/org.eclipse.core.resources.prefs rename to zipeditor.feature/.settings/org.eclipse.core.resources.prefs index 370ae2c..99f26c0 100644 --- a/ZipEditor Feature/.settings/org.eclipse.core.resources.prefs +++ b/zipeditor.feature/.settings/org.eclipse.core.resources.prefs @@ -1,2 +1,2 @@ eclipse.preferences.version=1 -encoding/=ISO-8859-1 +encoding/=UTF-8 diff --git a/ZipEditor Feature/cpl10.txt b/zipeditor.feature/cpl10.txt similarity index 100% rename from ZipEditor Feature/cpl10.txt rename to zipeditor.feature/cpl10.txt diff --git a/zipeditor.feature/feature.xml b/zipeditor.feature/feature.xml new file mode 100644 index 0000000..695f73c --- /dev/null +++ b/zipeditor.feature/feature.xml @@ -0,0 +1,266 @@ + + + + + An Eclipse editor to manipulate archives. +1.2.0 +--------------------- +- zstd zip encoding support +1.1.9 +--------------------- +- Support search within non-archive files as well +1.1.8 +--------------------- +- Replaced some references to deprecated types/methods +1.1.7 +--------------------- +- https://sourceforge.net/p/zipeditor/bugs/14/ remove references to org.eclipse.jface.util.Assert +1.1.6 +--------------------- +- https://sourceforge.net/p/zipeditor/bugs/11/ disable debug by default +- https://sourceforge.net/p/zipeditor/bugs/12/ don't log too much +- https://sourceforge.net/p/zipeditor/bugs/13/ late opening of files +1.1.5 +--------------------- +- added RPM read functionality +- added method (compressed/stored) to zip entries +- save archive type specific editor settings +- general performance improvements +New in release 1.1.4 +--------------------- +- Ctrl+O in the editor opens a quick outline +- "Open in Zip Editor" can be used on build path entries +- Editors opened on search results show marker annotations for occurrences now.\ + +New in release 1.1.3 +--------------------- +- Use the Eclipse search to recursively search in archives. + + + + © Uwe Voigt, 2006, 2007. All Rights Reserved. + + + + THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS +COMMON 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 a Contributor +with respect to a patent applicable to software (including a +cross-claim or counterclaim in a lawsuit), then any patent licenses +granted by that Contributor to such Recipient under this Agreement +shall terminate as of the date such litigation is filed. In addition, +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. +IBM is the initial Agreement Steward. IBM 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. + + + + + + + + + + + + + diff --git a/zipeditor.feature/pom.xml b/zipeditor.feature/pom.xml new file mode 100644 index 0000000..8370dfa --- /dev/null +++ b/zipeditor.feature/pom.xml @@ -0,0 +1,72 @@ + + 4.0.0 + + zipeditor.feature + eclipse-feature + 1.2.1-SNAPSHOT + + .. + ZipEditor.parent + com.github + 1.0.0-SNAPSHOT + + Zip Editor Feature + This is the feature of the Zip editor + + + + + + org.eclipse.tycho + tycho-packaging-plugin + ${tycho.version} + + + default-validate-id + none + + + + + org.eclipse.tycho + tycho-maven-plugin + true + + + org.eclipse.tycho + tycho-packaging-plugin + ${tycho-version} + + + attach-sources + + package-feature + + + + + + + + + + localtarget + file:/${project.basedir}/../maven-bnd/site/target/repository/ + p2 + + + eclipse 2025-06 + http://download.eclipse.org/releases/2025-06 + p2 + + + apache-repository + https://repository.apache.org/content/repositories/snapshots + + true + + + +