001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.compress.java.util.jar; 018 019import java.beans.PropertyChangeListener; 020import java.io.File; 021import java.io.IOException; 022import java.io.InputStream; 023import java.io.OutputStream; 024import java.security.AccessController; 025import java.security.PrivilegedAction; 026import java.util.SortedMap; 027import java.util.jar.JarFile; 028import java.util.jar.JarInputStream; 029import java.util.jar.JarOutputStream; 030 031import org.apache.commons.compress.harmony.archive.internal.nls.Messages; 032 033/** 034 * Class factory for {@link Pack200.Packer} and {@link Pack200.Unpacker}. 035 */ 036public abstract class Pack200 { 037 038 private static final String SYSTEM_PROPERTY_PACKER = "java.util.jar.Pack200.Packer"; //$NON-NLS-1$ 039 040 private static final String SYSTEM_PROPERTY_UNPACKER = "java.util.jar.Pack200.Unpacker"; //$NON-NLS-1$ 041 042 /** 043 * Prevent this class from being instantiated. 044 */ 045 private Pack200() { 046 // do nothing 047 } 048 049 /** 050 * Returns a new instance of a packer engine. 051 * <p> 052 * The implementation of the packer engine is defined by the system property 053 * {@code 'java.util.jar.Pack200.Packer'}. If this system property is 054 * defined an instance of the specified class is returned, otherwise the 055 * system's default implementation is returned. 056 * 057 * @return an instance of {@code Packer} 058 */ 059 public static Pack200.Packer newPacker() { 060 return (Packer) AccessController 061 .doPrivileged(new PrivilegedAction<Object>() { 062 public Object run() { 063 String className = System 064 .getProperty(SYSTEM_PROPERTY_PACKER, 065 "org.apache.commons.compress.harmony.pack200.Pack200PackerAdapter"); //$NON-NLS-1$ 066 try { 067 // TODO Not sure if this will cause problems with 068 // loading the packer 069 return ClassLoader.getSystemClassLoader() 070 .loadClass(className).newInstance(); 071 } catch (Exception e) { 072 throw new Error(Messages.getString("archive.3E",className), e); //$NON-NLS-1$ 073 } 074 } 075 }); 076 077 } 078 079 /** 080 * Returns a new instance of a unpacker engine. 081 * <p> 082 * The implementation of the unpacker engine is defined by the system 083 * property {@code 'java.util.jar.Pack200.Unpacker'}. If this system 084 * property is defined an instance of the specified class is returned, 085 * otherwise the system's default implementation is returned. 086 * 087 * @return a instance of {@code Unpacker}. 088 */ 089 public static Pack200.Unpacker newUnpacker() { 090 return (Unpacker) AccessController 091 .doPrivileged(new PrivilegedAction<Object>() { 092 public Object run() { 093 String className = System 094 .getProperty(SYSTEM_PROPERTY_UNPACKER, 095 "org.apache.commons.compress.harmony.unpack200.Pack200UnpackerAdapter");//$NON-NLS-1$ 096 try { 097 return ClassLoader.getSystemClassLoader() 098 .loadClass(className).newInstance(); 099 } catch (Exception e) { 100 throw new Error(Messages.getString("archive.3E",className), e); //$NON-NLS-1$ 101 } 102 } 103 }); 104 } 105 106 /** 107 * The interface defining the API for converting a JAR file to an output 108 * stream in the Pack200 format. 109 */ 110 public static interface Packer { 111 112 /** 113 * the format of a class attribute name. 114 */ 115 static final String CLASS_ATTRIBUTE_PFX = "pack.class.attribute."; //$NON-NLS-1$ 116 117 /** 118 * the format of a code attribute name. 119 */ 120 static final String CODE_ATTRIBUTE_PFX = "pack.code.attribute."; //$NON-NLS-1$ 121 122 /** 123 * the deflation hint to set in the output archive. 124 */ 125 static final String DEFLATE_HINT = "pack.deflate.hint";//$NON-NLS-1$ 126 127 /** 128 * the indicated amount of effort to use in compressing the archive. 129 */ 130 static final String EFFORT = "pack.effort";//$NON-NLS-1$ 131 132 /** 133 * a String representation for {@code error}. 134 */ 135 static final String ERROR = "error";//$NON-NLS-1$ 136 137 /** 138 * a String representation of {@code false}. 139 */ 140 static final String FALSE = "false";//$NON-NLS-1$ 141 142 /** 143 * the format of a field attribute name. 144 */ 145 static final String FIELD_ATTRIBUTE_PFX = "pack.field.attribute.";//$NON-NLS-1$ 146 147 /** 148 * a String representation for {@code keep}. 149 */ 150 static final String KEEP = "keep";//$NON-NLS-1$ 151 152 /** 153 * decide if all elements shall transmit in their original order. 154 */ 155 static final String KEEP_FILE_ORDER = "pack.keep.file.order";//$NON-NLS-1$ 156 157 /** 158 * a String representation for {@code latest}. 159 */ 160 static final String LATEST = "latest";//$NON-NLS-1$ 161 162 /** 163 * the format of a method attribute name. 164 */ 165 static final String METHOD_ATTRIBUTE_PFX = "pack.method.attribute.";//$NON-NLS-1$ 166 167 /** 168 * if it shall attempt to determine the latest modification time if this 169 * is set to {@code LATEST}. 170 */ 171 static final String MODIFICATION_TIME = "pack.modification.time";//$NON-NLS-1$ 172 173 /** 174 * a String representation of {@code pass}. 175 */ 176 static final String PASS = "pass";//$NON-NLS-1$ 177 178 /** 179 * the file that will not be compressed. 180 */ 181 static final String PASS_FILE_PFX = "pack.pass.file.";//$NON-NLS-1$ 182 183 /** 184 * packer progress as a percentage. 185 */ 186 static final String PROGRESS = "pack.progress";//$NON-NLS-1$ 187 188 /** 189 * The number of bytes of each archive segment. 190 */ 191 static final String SEGMENT_LIMIT = "pack.segment.limit";//$NON-NLS-1$ 192 193 /** 194 * a String representation of {@code strip}. 195 */ 196 static final String STRIP = "strip";//$NON-NLS-1$ 197 198 /** 199 * a String representation of {@code true}. 200 */ 201 static final String TRUE = "true";//$NON-NLS-1$ 202 203 /** 204 * the action to take if an unknown attribute is encountered. 205 */ 206 static final String UNKNOWN_ATTRIBUTE = "pack.unknown.attribute";//$NON-NLS-1$ 207 208 /** 209 * Returns a sorted map of the properties of this packer. 210 * 211 * @return the properties of the packer. 212 */ 213 SortedMap<String, String> properties(); 214 215 /** 216 * Pack the specified JAR file to the specified output stream. 217 * 218 * @param in 219 * JAR file to be compressed. 220 * @param out 221 * stream of compressed data. 222 * @throws IOException 223 * if I/O exception occurs. 224 */ 225 void pack(JarFile in, OutputStream out) throws IOException; 226 227 /** 228 * Pack the data from the specified jar input stream to the specified 229 * output stream. 230 * 231 * @param in 232 * stream of uncompressed JAR data. 233 * @param out 234 * stream of compressed data. 235 * @throws IOException 236 * if I/O exception occurs. 237 */ 238 void pack(JarInputStream in, OutputStream out) throws IOException; 239 240 /** 241 * add a listener for PropertyChange events 242 * 243 * @param listener 244 * the listener to listen if PropertyChange events occurs 245 */ 246 void addPropertyChangeListener(PropertyChangeListener listener); 247 248 /** 249 * remove a listener 250 * 251 * @param listener 252 * listener to remove 253 */ 254 void removePropertyChangeListener(PropertyChangeListener listener); 255 } 256 257 /** 258 * The interface defining the API for converting a packed stream in the 259 * Pack200 format to a JAR file. 260 */ 261 public static interface Unpacker { 262 263 /** 264 * The String indicating if the unpacker should ignore all transmitted 265 * values,can be replaced by either {@code true} or {@code false}. 266 */ 267 static final String DEFLATE_HINT = "unpack.deflate.hint";//$NON-NLS-1$ 268 269 /** 270 * a String representation of {@code false}. 271 */ 272 static final String FALSE = "false";//$NON-NLS-1$ 273 274 /** 275 * a String representation of {@code keep}. 276 */ 277 static final String KEEP = "keep";//$NON-NLS-1$ 278 279 /** 280 * the progress as a {@code percentage}. 281 */ 282 static final String PROGRESS = "unpack.progress";//$NON-NLS-1$ 283 284 /** 285 * a String representation of {@code true}. 286 */ 287 static final String TRUE = "true";//$NON-NLS-1$ 288 289 /** 290 * Returns a sorted map of the properties of this unpacker. 291 * 292 * @return the properties of unpacker. 293 */ 294 SortedMap<String, String> properties(); 295 296 /** 297 * Unpack the specified stream to the specified JAR output stream. 298 * 299 * @param in 300 * stream to uncompressed. 301 * @param out 302 * JAR output stream of uncompressed data. 303 * @throws IOException 304 * if I/O exception occurs. 305 */ 306 void unpack(InputStream in, JarOutputStream out) throws IOException; 307 308 /** 309 * Unpack the contents of the specified {@code File} to the specified 310 * JAR output stream. 311 * 312 * @param in 313 * file to be uncompressed. 314 * @param out 315 * JAR output stream of uncompressed data. 316 * @throws IOException 317 * if I/O exception occurs. 318 */ 319 void unpack(File in, JarOutputStream out) throws IOException; 320 321 /** 322 * add a listener for {@code PropertyChange} events. 323 * 324 * @param listener 325 * the listener to listen if {@code PropertyChange} events 326 * occurs. 327 */ 328 void addPropertyChangeListener(PropertyChangeListener listener); 329 330 /** 331 * remove a listener. 332 * 333 * @param listener 334 * listener to remove. 335 */ 336 void removePropertyChangeListener(PropertyChangeListener listener); 337 } 338 339}