src/share/classes/com/sun/java/util/jar/pack/PropMap.java

Print this page




   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.java.util.jar.pack;
  27 
  28 import java.beans.PropertyChangeListener;
  29 import java.beans.PropertyChangeEvent;
  30 import java.io.IOException;
  31 import java.io.InputStream;
  32 import java.io.PrintStream;
  33 import java.io.PrintWriter;
  34 import java.util.ArrayList;
  35 import java.util.Collection;
  36 import java.util.Comparator;
  37 import java.util.HashMap;
  38 import java.util.List;
  39 import java.util.Map;
  40 import java.util.Properties;
  41 import java.util.Set;
  42 import java.util.SortedMap;
  43 import java.util.TreeMap;
  44 import java.util.jar.Pack200;




  45 /**
  46  * Control block for publishing Pack200 options to the other classes.
  47  */
  48 
  49 final class PropMap implements SortedMap<String, String>  {
  50     private final TreeMap<String, String> theMap = new TreeMap<>();;
  51     private final List<PropertyChangeListener> listenerList = new ArrayList<>(1);
  52 
  53     void addListener(PropertyChangeListener listener) {




  54         listenerList.add(listener);
  55     }
  56 
  57     void removeListener(PropertyChangeListener listener) {

  58         listenerList.remove(listener);
  59     }
  60 
  61     void addListeners(ArrayList<PropertyChangeListener> listeners) {
  62         listenerList.addAll(listeners);
  63     }
  64 
  65     void removeListeners(ArrayList<PropertyChangeListener> listeners) {
  66         listenerList.removeAll(listeners);
  67     }
  68 
  69     // Override:
  70     public String put(String key, String value) {
  71         String oldValue = theMap.put(key, value);
  72         if (value != oldValue && !listenerList.isEmpty()) {

  73             // Post the property change event.
  74             PropertyChangeEvent event =
  75                 new PropertyChangeEvent(this, key,
  76                                         oldValue, value);
  77             for (PropertyChangeListener listener : listenerList) {
  78                 listener.propertyChange(event);
  79             }
  80         }
  81         return oldValue;
  82     }
  83 
  84     // All this other stuff is private to the current package.
  85     // Outide clients of Pack200 do not need to use it; they can
  86     // get by with generic SortedMap functionality.
  87     private static Map<String, String> defaultProps;
  88     static {
  89         Properties props = new Properties();
  90 
  91         // Allow implementation selected via -Dpack.disable.native=true
  92         props.put(Utils.DEBUG_DISABLE_NATIVE,
  93                   String.valueOf(Boolean.getBoolean(Utils.DEBUG_DISABLE_NATIVE)));
  94 
  95         // Set the DEBUG_VERBOSE from system
  96         props.put(Utils.DEBUG_VERBOSE,
  97                   String.valueOf(Integer.getInteger(Utils.DEBUG_VERBOSE,0)));
  98 


 322 
 323     @Override
 324     public SortedMap<String, String> headMap(String toKey) {
 325         return theMap.headMap(toKey);
 326     }
 327 
 328     @Override
 329     public SortedMap<String, String> tailMap(String fromKey) {
 330         return theMap.tailMap(fromKey);
 331     }
 332 
 333     @Override
 334     public String firstKey() {
 335         return theMap.firstKey();
 336     }
 337 
 338     @Override
 339     public String lastKey() {
 340        return theMap.lastKey();
 341     }













































































































 342 }


   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.java.util.jar.pack;
  27 


  28 import java.io.IOException;
  29 import java.io.InputStream;
  30 import java.io.PrintStream;
  31 import java.io.PrintWriter;
  32 import java.util.ArrayList;
  33 import java.util.Collection;
  34 import java.util.Comparator;
  35 import java.util.HashMap;
  36 import java.util.List;
  37 import java.util.Map;
  38 import java.util.Properties;
  39 import java.util.Set;
  40 import java.util.SortedMap;
  41 import java.util.TreeMap;
  42 import java.util.jar.Pack200;
  43 import java.lang.reflect.Constructor;
  44 import java.lang.reflect.InvocationTargetException;
  45 import java.lang.reflect.Method;
  46 
  47 /**
  48  * Control block for publishing Pack200 options to the other classes.
  49  */
  50 
  51 final class PropMap implements SortedMap<String, String>  {
  52     private final TreeMap<String, String> theMap = new TreeMap<>();;

  53 
  54     // type is erased, elements are of type java.beans.PropertyChangeListener
  55     private final List<Object> listenerList = new ArrayList<>(1);
  56 
  57     void addListener(Object listener) {
  58         assert Beans.isPropertyChangeListener(listener);
  59         listenerList.add(listener);
  60     }
  61 
  62     void removeListener(Object listener) {
  63         assert Beans.isPropertyChangeListener(listener);
  64         listenerList.remove(listener);
  65     }
  66 








  67     // Override:
  68     public String put(String key, String value) {
  69         String oldValue = theMap.put(key, value);
  70         if (value != oldValue && !listenerList.isEmpty()) {
  71             assert Beans.isBeansPresent();
  72             // Post the property change event.
  73             Object event = Beans.newPropertyChangeEvent(this, key, oldValue, value);
  74             for (Object listener : listenerList) {
  75                 Beans.invokePropertyChange(listener, event);


  76             }
  77         }
  78         return oldValue;
  79     }
  80 
  81     // All this other stuff is private to the current package.
  82     // Outide clients of Pack200 do not need to use it; they can
  83     // get by with generic SortedMap functionality.
  84     private static Map<String, String> defaultProps;
  85     static {
  86         Properties props = new Properties();
  87 
  88         // Allow implementation selected via -Dpack.disable.native=true
  89         props.put(Utils.DEBUG_DISABLE_NATIVE,
  90                   String.valueOf(Boolean.getBoolean(Utils.DEBUG_DISABLE_NATIVE)));
  91 
  92         // Set the DEBUG_VERBOSE from system
  93         props.put(Utils.DEBUG_VERBOSE,
  94                   String.valueOf(Integer.getInteger(Utils.DEBUG_VERBOSE,0)));
  95 


 319 
 320     @Override
 321     public SortedMap<String, String> headMap(String toKey) {
 322         return theMap.headMap(toKey);
 323     }
 324 
 325     @Override
 326     public SortedMap<String, String> tailMap(String fromKey) {
 327         return theMap.tailMap(fromKey);
 328     }
 329 
 330     @Override
 331     public String firstKey() {
 332         return theMap.firstKey();
 333     }
 334 
 335     @Override
 336     public String lastKey() {
 337        return theMap.lastKey();
 338     }
 339     
 340     /**
 341      * A class that provides access to the java.beans.PropertyChangeListener
 342      * and java.beans.PropertyChangeEvent without creating a static dependency
 343      * on java.beans. This class can be removed once the addPropertyChangeListener
 344      * and removePropertyChangeListener methods are removed from Packer and
 345      * Unpacker.
 346      */
 347     private static class Beans {
 348         private static final Class<?> propertyChangeListenerClass = 
 349             getClass("java.beans.PropertyChangeListener");
 350         
 351         private static final Class<?> propertyChangeEventClass = 
 352             getClass("java.beans.PropertyChangeEvent");      
 353         
 354         private static final Method propertyChangeMethod = 
 355             getMethod(propertyChangeListenerClass, 
 356                       "propertyChange", 
 357                       propertyChangeEventClass);
 358         
 359         private static final Constructor<?> propertyEventCtor = 
 360             getConstructor(propertyChangeEventClass, 
 361                            Object.class, 
 362                            String.class, 
 363                            Object.class, 
 364                            Object.class);
 365 
 366         private static Class<?> getClass(String name) {
 367             try {
 368                 return Class.forName(name, true, Beans.class.getClassLoader());
 369             } catch (ClassNotFoundException e) {
 370                 return null;
 371             }
 372         }
 373         private static Constructor<?> getConstructor(Class<?> c, Class<?>... types) {
 374             try {
 375                 return (c == null) ? null : c.getDeclaredConstructor(types);
 376             } catch (NoSuchMethodException x) {
 377                 throw new AssertionError(x);
 378             }
 379         }
 380 
 381         private static Method getMethod(Class<?> c, String name, Class<?>... types) {
 382             try {
 383                 return (c == null) ? null : c.getMethod(name, types);
 384             } catch (NoSuchMethodException e) {
 385                 throw new AssertionError(e);
 386             }
 387         }      
 388         
 389         /**
 390          * Returns {@code true} if java.beans is present.
 391          */
 392         static boolean isBeansPresent() {
 393             return propertyChangeListenerClass != null && 
 394                    propertyChangeEventClass != null;
 395         }
 396         
 397         /**
 398          * Returns {@code true} if the given object is a PropertyChangeListener
 399          */
 400         static boolean isPropertyChangeListener(Object obj) {
 401             if (propertyChangeListenerClass == null) {
 402                 return false;
 403             } else {
 404                 return propertyChangeListenerClass.isInstance(obj);
 405             }
 406         }
 407         
 408         /**
 409          * Returns a new PropertyChangeEvent with the given source, property
 410          * name, old and new values.
 411          */
 412         static Object newPropertyChangeEvent(Object source, String prop, 
 413                                              Object oldValue, Object newValue)
 414         {
 415             try {
 416                 return propertyEventCtor.newInstance(source, prop, oldValue, newValue);
 417             } catch (InstantiationException | IllegalAccessException x) {
 418                 throw new AssertionError(x);
 419             } catch (InvocationTargetException x) {
 420                 Throwable cause = x.getCause();
 421                 if (cause instanceof Error)
 422                     throw (Error)cause;
 423                 if (cause instanceof RuntimeException)
 424                     throw (RuntimeException)cause;
 425                 throw new AssertionError(x);
 426             }
 427         }
 428         
 429         /**
 430          * Invokes the given PropertyChangeListern's propertyChange method
 431          * with the given event.
 432          */
 433         static void invokePropertyChange(Object listener, Object ev) {
 434             try {
 435                 propertyChangeMethod.invoke(listener, ev);
 436             } catch (IllegalAccessException x) {
 437                 throw new AssertionError(x);
 438             } catch (InvocationTargetException x) {
 439                 Throwable cause = x.getCause();
 440                 if (cause instanceof Error)
 441                     throw (Error)cause;
 442                 if (cause instanceof RuntimeException)
 443                     throw (RuntimeException)cause;
 444                 throw new AssertionError(x);
 445             }
 446         }
 447     }
 448 }