1 /*
   2  * $Id$
   3  *
   4  * Copyright (c) 2001, 2009, Oracle and/or its affiliates. All rights reserved.
   5  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   6  *
   7  * This code is free software; you can redistribute it and/or modify it
   8  * under the terms of the GNU General Public License version 2 only, as
   9  * published by the Free Software Foundation.  Oracle designates this
  10  * particular file as subject to the "Classpath" exception as provided
  11  * by Oracle in the LICENSE file that accompanied this code.
  12  *
  13  * This code is distributed in the hope that it will be useful, but WITHOUT
  14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  15  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  16  * version 2 for more details (a copy is included in the LICENSE file that
  17  * accompanied this code).
  18  *
  19  * You should have received a copy of the GNU General Public License version
  20  * 2 along with this work; if not, write to the Free Software Foundation,
  21  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  22  *
  23  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  24  * or visit www.oracle.com if you need additional information or have any
  25  * questions.
  26  */
  27 package com.sun.javatest.util;
  28 
  29 import java.util.Collection;
  30 import java.util.HashMap;
  31 import java.util.HashSet;
  32 import java.util.Iterator;
  33 import java.util.Map;
  34 import java.util.Set;
  35 import java.util.Vector;
  36 
  37 /**
  38  * A map whose entries are stored in a parent map by prefixing
  39  * the key names with a specific string.
  40  */
  41 public class PrefixMap<V> implements Map<String, V>
  42 {
  43     /**
  44      * Create a map whose entries are stored in a parent map
  45      * by prefixing the key names with a specific string.
  46      * @param map the parent map
  47      * @param prefix the prefix with which to prefix the entries in the
  48      * parent map
  49      */
  50     public PrefixMap(Map<String, V> map, String prefix) {
  51         this.map = map;
  52         this.prefix = prefix + ".";
  53     }
  54 
  55     public void clear() {
  56         for (Iterator<String> i = map.keySet().iterator(); i.hasNext(); ) {
  57             String key = i.next();
  58             if (key.startsWith(prefix))
  59                 i.remove();
  60         }
  61     }
  62 
  63     /**
  64      * Get the prefix that this map is applying.
  65      * This is the value that was supplied to the constructor.  This class
  66      * reserves the right to return a String which is not reference equivalent
  67      * to the given string.
  68      * @return The prefix string, which may be a zero length string.
  69      */
  70     public String getPrefix() {
  71         // protect against zero length prefix
  72         if (prefix.length() > 1)
  73             return prefix.substring(0, prefix.length() - 1);
  74         else
  75             return "";
  76     }
  77 
  78     public boolean containsKey(Object key) {
  79         return map.containsKey(prefix + key);
  80     }
  81 
  82     public boolean containsValue(Object value) {
  83         for (Iterator<Map.Entry<String, V>> i = map.entrySet().iterator(); i.hasNext(); ) {
  84             Map.Entry<String, V> e = i.next();
  85             String key = e.getKey();
  86             if (key.startsWith(prefix) && e.getValue().equals(value))
  87                 return true;
  88         }
  89         return false;
  90     }
  91 
  92     public Set<Map.Entry<String, V>> entrySet() {
  93         Map<String, V> m = new HashMap<String, V>();
  94         for (Iterator<Map.Entry<String, V>> i = map.entrySet().iterator(); i.hasNext(); ) {
  95             Map.Entry<String, V> e = i.next();
  96             String key = e.getKey();
  97             if (key.startsWith(prefix))
  98                 m.put(key.substring(prefix.length()), e.getValue());
  99         }
 100         return m.entrySet();
 101     }
 102 
 103     public V get(Object key) {
 104         return map.get(prefix + key);
 105     }
 106 
 107     public int hashCode() {
 108         return (map.hashCode() + prefix.hashCode());
 109     }
 110 
 111     public boolean isEmpty() {
 112         for (Iterator<String> i = map.keySet().iterator(); i.hasNext(); ) {
 113             String key = i.next();
 114             if (key.startsWith(prefix))
 115                 return false;
 116         }
 117         return true;
 118     }
 119 
 120     public Set<String> keySet() {
 121         Set<String> s = new HashSet<>();
 122         for (Iterator<String> i = map.keySet().iterator(); i.hasNext(); ) {
 123             String key = i.next();
 124             if (key.startsWith(prefix))
 125                 s.add(key.substring(prefix.length()));
 126         }
 127         return s;
 128     }
 129 
 130     public V put(String key, V value) {
 131         return map.put(prefix + key, value);
 132     }
 133 
 134     public void putAll(Map<? extends String, ? extends V> t) {
 135         for (Iterator<? extends Entry<? extends String, ? extends V>> i = t.entrySet().iterator(); i.hasNext(); ) {
 136             Map.Entry<? extends String, ? extends V> e = i.next();
 137             String key = e.getKey();
 138             put(key, e.getValue());
 139         }
 140     }
 141 
 142     public V remove(Object key) {
 143         return map.remove(prefix + key);
 144     }
 145 
 146     public int size() {
 147         int n = 0;
 148         for (Iterator<String> i = map.keySet().iterator(); i.hasNext(); ) {
 149             String key = (i.next());
 150             if (key.startsWith(prefix))
 151                 n++;
 152         }
 153         return n;
 154     }
 155 
 156     public Collection<V> values() {
 157         Collection<V> c = new Vector<>();
 158         for (Iterator<Map.Entry<String, V>> i = map.entrySet().iterator(); i.hasNext(); ) {
 159             Map.Entry<String, V> e = i.next();
 160             String key = e.getKey();
 161             if (key.startsWith(prefix))
 162                 c.add(e.getValue());
 163         }
 164         return c;
 165     }
 166 
 167     private Map<String, V> map;
 168     private String prefix;
 169 }