diff options
author | Thomas Watson | 2017-01-18 22:08:34 +0000 |
---|---|---|
committer | Thomas Watson | 2017-01-18 22:08:34 +0000 |
commit | bd50cc83c991934e6891354e1849f2beec4ca48f (patch) | |
tree | 0c257871de8f11fa43b19be64fa13feb5caf12d7 /bundles | |
parent | c8caeaa2cf5f6621f755dd7878a911e77147ea88 (diff) | |
download | rt.equinox.framework-bd50cc83c991934e6891354e1849f2beec4ca48f.tar.gz rt.equinox.framework-bd50cc83c991934e6891354e1849f2beec4ca48f.tar.xz rt.equinox.framework-bd50cc83c991934e6891354e1849f2beec4ca48f.zip |
Restore Headers temporarily.Y20170202-1000Y20170126-1700Y20170126-1000Y20170119-1000S4_7_0_M5I20170202-2000I20170201-2000I20170131-2000I20170130-2000I20170130-0600I20170129-2000I20170128-2000I20170127-2200I20170127-2000I20170126-1030I20170126-0505I20170125-2000I20170125-0800I20170124-2000I20170124-0800I20170123-2000I20170123-0830I20170123-0800I20170122-2000I20170121-2000I20170121-0950I20170120-2000I20170119-2000I20170119-1010I20170119-0345I20170118-2000
Change-Id: I202447a6279febe848c5db0b2c301650b06274f6
Signed-off-by: Thomas Watson <tjwatson@us.ibm.com>
Diffstat (limited to 'bundles')
-rw-r--r-- | bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/framework/util/Headers.java | 338 |
1 files changed, 338 insertions, 0 deletions
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/framework/util/Headers.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/framework/util/Headers.java new file mode 100644 index 000000000..0a03d8d29 --- /dev/null +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/framework/util/Headers.java @@ -0,0 +1,338 @@ +/******************************************************************************* + * Copyright (c) 2003, 2017 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package org.eclipse.osgi.framework.util; + +import java.io.IOException; +import java.io.InputStream; +import java.util.*; +import org.eclipse.osgi.internal.messages.Msg; +import org.eclipse.osgi.util.ManifestElement; +import org.eclipse.osgi.util.NLS; +import org.osgi.framework.BundleException; + +/** + * Headers classes. This class implements a Dictionary that has + * the following behavior: + * <ul> + * <li>put and remove clear throw UnsupportedOperationException. + * The Dictionary is thus read-only to others. + * <li>The String keys in the Dictionary are case-preserved, + * but the get operation is case-insensitive. + * </ul> + * @since 3.1 + * @deprecated As of 3.13. Replaced by {@link CaseInsensitiveDictionaryMap}. + */ +@Deprecated +public class Headers<K, V> extends Dictionary<K, V> implements Map<K, V> { + private boolean readOnly = false; + private K[] headers; + private V[] values; + private int size = 0; + + /** + * Create an empty Headers dictionary. + * + * @param initialCapacity The initial capacity of this Headers object. + */ + public Headers(int initialCapacity) { + super(); + @SuppressWarnings("unchecked") + K[] k = (K[]) new Object[initialCapacity]; + headers = k; + @SuppressWarnings("unchecked") + V[] v = (V[]) new Object[initialCapacity]; + values = v; + } + + /** + * Create a Headers dictionary from a Dictionary. + * + * @param values The initial dictionary for this Headers object. + * @exception IllegalArgumentException If a case-variant of the key is + * in the dictionary parameter. + */ + public Headers(Dictionary<? extends K, ? extends V> values) { + this(values.size()); + /* initialize the headers and values */ + Enumeration<? extends K> keys = values.keys(); + while (keys.hasMoreElements()) { + K key = keys.nextElement(); + set(key, values.get(key)); + } + } + + /** + * Case-preserved keys. + */ + public synchronized Enumeration<K> keys() { + return new ArrayEnumeration<>(headers, size); + } + + /** + * Values. + */ + public synchronized Enumeration<V> elements() { + return new ArrayEnumeration<>(values, size); + } + + private int getIndex(Object key) { + boolean stringKey = key instanceof String; + for (int i = 0; i < size; i++) { + if (stringKey && (headers[i] instanceof String)) { + if (((String) headers[i]).equalsIgnoreCase((String) key)) + return i; + } else { + if (headers[i].equals(key)) + return i; + } + } + return -1; + } + + private V remove(int remove) { + V removed = values[remove]; + for (int i = remove; i < size; i++) { + if (i == headers.length - 1) { + headers[i] = null; + values[i] = null; + } else { + headers[i] = headers[i + 1]; + values[i] = values[i + 1]; + } + } + if (remove < size) + size--; + return removed; + } + + private void add(K header, V value) { + if (size == headers.length) { + // grow the arrays + @SuppressWarnings("unchecked") + K[] nh = (K[]) new Object[headers.length + 10]; + K[] newHeaders = nh; + @SuppressWarnings("unchecked") + V[] nv = (V[]) new Object[values.length + 10]; + V[] newValues = nv; + System.arraycopy(headers, 0, newHeaders, 0, headers.length); + System.arraycopy(values, 0, newValues, 0, values.length); + headers = newHeaders; + values = newValues; + } + headers[size] = header; + values[size] = value; + size++; + } + + /** + * Support case-insensitivity for keys. + * + * @param key name. + */ + public synchronized V get(Object key) { + int i = -1; + if ((i = getIndex(key)) != -1) + return values[i]; + return null; + } + + /** + * Set a header value or optionally replace it if it already exists. + * + * @param key Key name. + * @param value Value of the key or null to remove key. + * @param replace A value of true will allow a previous + * value of the key to be replaced. A value of false + * will cause an IllegalArgumentException to be thrown + * if a previous value of the key exists. + * @return the previous value to which the key was mapped, + * or null if the key did not have a previous mapping. + * + * @exception IllegalArgumentException If a case-variant of the key is + * already present. + * @since 3.2 + */ + public synchronized V set(K key, V value, boolean replace) { + if (readOnly) + throw new UnsupportedOperationException(); + if (key instanceof String) { + @SuppressWarnings("unchecked") + K k = (K) ((String) key).intern(); + key = k; + } + int i = getIndex(key); + if (value == null) { /* remove */ + if (i != -1) + return remove(i); + } else { /* put */ + if (i != -1) { /* duplicate key */ + if (!replace) + throw new IllegalArgumentException(NLS.bind(Msg.HEADER_DUPLICATE_KEY_EXCEPTION, key)); + V oldVal = values[i]; + values[i] = value; + return oldVal; + } + add(key, value); + } + return null; + } + + /** + * Set a header value. + * + * @param key Key name. + * @param value Value of the key or null to remove key. + * @return the previous value to which the key was mapped, + * or null if the key did not have a previous mapping. + * + * @exception IllegalArgumentException If a case-variant of the key is + * already present. + */ + public synchronized V set(K key, V value) { + return set(key, value, false); + } + + public synchronized void setReadOnly() { + readOnly = true; + } + + /** + * Returns the number of entries (distinct keys) in this dictionary. + * + * @return the number of keys in this dictionary. + */ + public synchronized int size() { + return size; + } + + /** + * Tests if this dictionary maps no keys to value. The general contract + * for the <tt>isEmpty</tt> method is that the result is true if and only + * if this dictionary contains no entries. + * + * @return <code>true</code> if this dictionary maps no keys to values; + * <code>false</code> otherwise. + */ + public synchronized boolean isEmpty() { + return size == 0; + } + + /** + * Always throws UnsupportedOperationException. + * + * @param key header name. + * @param value header value. + * @throws UnsupportedOperationException + */ + public synchronized V put(K key, V value) { + if (readOnly) + throw new UnsupportedOperationException(); + return set(key, value, true); + } + + /** + * Always throws UnsupportedOperationException. + * + * @param key header name. + * @throws UnsupportedOperationException + */ + public V remove(Object key) { + throw new UnsupportedOperationException(); + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append('{'); + + for (int i = 0; i < size; i++) { + if (i != 0) { + sb.append(", "); //$NON-NLS-1$ + } + K header = headers[i]; + if (header == this) { + sb.append("(this Dictionary)"); //$NON-NLS-1$ + } else { + sb.append(header); + } + sb.append('='); + V value = values[i]; + if (value == this) { + sb.append("(this Dictionary)"); //$NON-NLS-1$ + } else { + sb.append(value); + } + } + + sb.append('}'); + return sb.toString(); + } + + public static Headers<String, String> parseManifest(InputStream in) throws BundleException { + Headers<String, String> headers = new Headers<>(10); + try { + ManifestElement.parseBundleManifest(in, headers); + } catch (IOException e) { + throw new BundleException(Msg.MANIFEST_IOEXCEPTION, BundleException.MANIFEST_ERROR, e); + } + headers.setReadOnly(); + return headers; + } + + private static class ArrayEnumeration<E> implements Enumeration<E> { + private E[] array; + int cur = 0; + + public ArrayEnumeration(E[] array, int size) { + @SuppressWarnings("unchecked") + E[] a = (E[]) new Object[size]; + this.array = a; + System.arraycopy(array, 0, this.array, 0, this.array.length); + } + + public boolean hasMoreElements() { + return cur < array.length; + } + + public E nextElement() { + return array[cur++]; + } + } + + public synchronized void clear() { + if (readOnly) + throw new UnsupportedOperationException(); + } + + public synchronized boolean containsKey(Object key) { + return getIndex(key) >= 0; + } + + public boolean containsValue(Object value) { + throw new UnsupportedOperationException(); + } + + public Set<Map.Entry<K, V>> entrySet() { + throw new UnsupportedOperationException(); + } + + public Set<K> keySet() { + throw new UnsupportedOperationException(); + } + + public void putAll(Map<? extends K, ? extends V> c) { + throw new UnsupportedOperationException(); + } + + public Collection<V> values() { + throw new UnsupportedOperationException(); + } +} |