1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package java.util.jar; 18 19 import java.beans.PropertyChangeListener; 20 import java.io.File; 21 import java.io.IOException; 22 import java.io.InputStream; 23 import java.io.OutputStream; 24 import java.security.AccessController; 25 import java.security.PrivilegedAction; 26 import java.util.SortedMap; 27 28 /** 29 * Class factory for {@link Pack200.Packer} and {@link Pack200.Unpacker}. 30 */ 31 public abstract class Pack200 { 32 33 private static final String SYSTEM_PROPERTY_PACKER = "java.util.jar.Pack200.Packer"; 34 35 private static final String SYSTEM_PROPERTY_UNPACKER = "java.util.jar.Pack200.Unpacker"; 36 37 /** 38 * Prevent this class from being instantiated. 39 */ 40 private Pack200() { 41 // do nothing 42 } 43 44 /** 45 * Returns a new instance of a packer engine. 46 * <p> 47 * The implementation of the packer engine is defined by the system property 48 * {@code 'java.util.jar.Pack200.Packer'}. If this system property is 49 * defined an instance of the specified class is returned, otherwise the 50 * system's default implementation is returned. 51 * 52 * @return an instance of {@code Packer} 53 */ 54 public static Pack200.Packer newPacker() { 55 return (Packer) AccessController 56 .doPrivileged(new PrivilegedAction<Object>() { 57 public Object run() { 58 String className = System 59 .getProperty(SYSTEM_PROPERTY_PACKER, 60 "org.apache.harmony.pack200.Pack200PackerAdapter"); 61 try { 62 // TODO Not sure if this will cause problems with 63 // loading the packer 64 return ClassLoader.getSystemClassLoader() 65 .loadClass(className).newInstance(); 66 } catch (Exception e) { 67 throw new Error("Can't load class " + className, e); 68 } 69 } 70 }); 71 72 } 73 74 /** 75 * Returns a new instance of a unpacker engine. 76 * <p> 77 * The implementation of the unpacker engine is defined by the system 78 * property {@code 'java.util.jar.Pack200.Unpacker'}. If this system 79 * property is defined an instance of the specified class is returned, 80 * otherwise the system's default implementation is returned. 81 * 82 * @return a instance of {@code Unpacker}. 83 */ 84 public static Pack200.Unpacker newUnpacker() { 85 return (Unpacker) AccessController 86 .doPrivileged(new PrivilegedAction<Object>() { 87 public Object run() { 88 String className = System 89 .getProperty(SYSTEM_PROPERTY_UNPACKER, 90 "org.apache.harmony.unpack200.Pack200UnpackerAdapter"); 91 try { 92 return ClassLoader.getSystemClassLoader() 93 .loadClass(className).newInstance(); 94 } catch (Exception e) { 95 throw new Error("Can't load class " + className, e); 96 } 97 } 98 }); 99 } 100 101 /** 102 * The interface defining the API for converting a JAR file to an output 103 * stream in the Pack200 format. 104 */ 105 public static interface Packer { 106 107 /** 108 * the format of a class attribute name. 109 */ 110 static final String CLASS_ATTRIBUTE_PFX = "pack.class.attribute."; 111 112 /** 113 * the format of a code attribute name. 114 */ 115 static final String CODE_ATTRIBUTE_PFX = "pack.code.attribute."; 116 117 /** 118 * the deflation hint to set in the output archive. 119 */ 120 static final String DEFLATE_HINT = "pack.deflate.hint"; 121 122 /** 123 * the indicated amount of effort to use in compressing the archive. 124 */ 125 static final String EFFORT = "pack.effort"; 126 127 /** 128 * a String representation for {@code error}. 129 */ 130 static final String ERROR = "error"; 131 132 /** 133 * a String representation of {@code false}. 134 */ 135 static final String FALSE = "false"; 136 137 /** 138 * the format of a field attribute name. 139 */ 140 static final String FIELD_ATTRIBUTE_PFX = "pack.field.attribute."; 141 142 /** 143 * a String representation for {@code keep}. 144 */ 145 static final String KEEP = "keep"; 146 147 /** 148 * decide if all elements shall transmit in their original order. 149 */ 150 static final String KEEP_FILE_ORDER = "pack.keep.file.order"; 151 152 /** 153 * a String representation for {@code latest}. 154 */ 155 static final String LATEST = "latest"; 156 157 /** 158 * the format of a method attribute name. 159 */ 160 static final String METHOD_ATTRIBUTE_PFX = "pack.method.attribute."; 161 162 /** 163 * if it shall attempt to determine the latest modification time if this 164 * is set to {@code LATEST}. 165 */ 166 static final String MODIFICATION_TIME = "pack.modification.time"; 167 168 /** 169 * a String representation of {@code pass}. 170 */ 171 static final String PASS = "pass"; 172 173 /** 174 * the file that will not be compressed. 175 */ 176 static final String PASS_FILE_PFX = "pack.pass.file."; 177 178 /** 179 * packer progress as a percentage. 180 */ 181 static final String PROGRESS = "pack.progress"; 182 183 /** 184 * The number of bytes of each archive segment. 185 */ 186 static final String SEGMENT_LIMIT = "pack.segment.limit"; 187 188 /** 189 * a String representation of {@code strip}. 190 */ 191 static final String STRIP = "strip"; 192 193 /** 194 * a String representation of {@code true}. 195 */ 196 static final String TRUE = "true"; 197 198 /** 199 * the action to take if an unknown attribute is encountered. 200 */ 201 static final String UNKNOWN_ATTRIBUTE = "pack.unknown.attribute"; 202 203 /** 204 * Returns a sorted map of the properties of this packer. 205 * 206 * @return the properties of the packer. 207 */ 208 SortedMap<String, String> properties(); 209 210 /** 211 * Pack the specified JAR file to the specified output stream. 212 * 213 * @param in 214 * JAR file to be compressed. 215 * @param out 216 * stream of compressed data. 217 * @throws IOException 218 * if I/O exception occurs. 219 */ 220 void pack(JarFile in, OutputStream out) throws IOException; 221 222 /** 223 * Pack the data from the specified jar input stream to the specified 224 * output stream. 225 * 226 * @param in 227 * stream of uncompressed JAR data. 228 * @param out 229 * stream of compressed data. 230 * @throws IOException 231 * if I/O exception occurs. 232 */ 233 void pack(JarInputStream in, OutputStream out) throws IOException; 234 235 /** 236 * add a listener for PropertyChange events 237 * 238 * @param listener 239 * the listener to listen if PropertyChange events occurs 240 */ 241 void addPropertyChangeListener(PropertyChangeListener listener); 242 243 /** 244 * remove a listener 245 * 246 * @param listener 247 * listener to remove 248 */ 249 void removePropertyChangeListener(PropertyChangeListener listener); 250 } 251 252 /** 253 * The interface defining the API for converting a packed stream in the 254 * Pack200 format to a JAR file. 255 */ 256 public static interface Unpacker { 257 258 /** 259 * The String indicating if the unpacker should ignore all transmitted 260 * values,can be replaced by either {@code true} or {@code false}. 261 */ 262 static final String DEFLATE_HINT = "unpack.deflate.hint"; 263 264 /** 265 * a String representation of {@code false}. 266 */ 267 static final String FALSE = "false"; 268 269 /** 270 * a String representation of {@code keep}. 271 */ 272 static final String KEEP = "keep"; 273 274 /** 275 * the progress as a {@code percentage}. 276 */ 277 static final String PROGRESS = "unpack.progress"; 278 279 /** 280 * a String representation of {@code true}. 281 */ 282 static final String TRUE = "true"; 283 284 /** 285 * Returns a sorted map of the properties of this unpacker. 286 * 287 * @return the properties of unpacker. 288 */ 289 SortedMap<String, String> properties(); 290 291 /** 292 * Unpack the specified stream to the specified JAR output stream. 293 * 294 * @param in 295 * stream to uncompressed. 296 * @param out 297 * JAR output stream of uncompressed data. 298 * @throws IOException 299 * if I/O exception occurs. 300 */ 301 void unpack(InputStream in, JarOutputStream out) throws IOException; 302 303 /** 304 * Unpack the contents of the specified {@code File} to the specified 305 * JAR output stream. 306 * 307 * @param in 308 * file to be uncompressed. 309 * @param out 310 * JAR output stream of uncompressed data. 311 * @throws IOException 312 * if I/O exception occurs. 313 */ 314 void unpack(File in, JarOutputStream out) throws IOException; 315 316 /** 317 * add a listener for {@code PropertyChange} events. 318 * 319 * @param listener 320 * the listener to listen if {@code PropertyChange} events 321 * occurs. 322 */ 323 void addPropertyChangeListener(PropertyChangeListener listener); 324 325 /** 326 * remove a listener. 327 * 328 * @param listener 329 * listener to remove. 330 */ 331 void removePropertyChangeListener(PropertyChangeListener listener); 332 } 333 334 } 335