Remove some generics warnings from the HPSF custom properties and sections parts

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@898804 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Nick Burch 2010-01-13 15:42:53 +00:00
parent 0d7ef148b5
commit 4cb27e5095
6 changed files with 110 additions and 62 deletions

View File

@ -49,21 +49,26 @@ import org.apache.poi.hpsf.wellknown.PropertyIDMap;
* <p>This class is not thread-safe; concurrent access to instances of this * <p>This class is not thread-safe; concurrent access to instances of this
* class must be synchronized.</p> * class must be synchronized.</p>
* *
* <p>While this class is roughly HashMap<Long,CustomProperty>, that's the
* internal representation. To external calls, it should appear as
* HashMap<String,Object> mapping between Names and Custom Property Values.</p>
*
* @author Rainer Klute <a * @author Rainer Klute <a
* href="mailto:klute@rainer-klute.de">&lt;klute@rainer-klute.de&gt;</a> * href="mailto:klute@rainer-klute.de">&lt;klute@rainer-klute.de&gt;</a>
*/ */
public class CustomProperties extends HashMap @SuppressWarnings("serial")
public class CustomProperties extends HashMap<Object,CustomProperty>
{ {
/** /**
* <p>Maps property IDs to property names.</p> * <p>Maps property IDs to property names.</p>
*/ */
private Map dictionaryIDToName = new HashMap(); private Map<Long,String> dictionaryIDToName = new HashMap<Long,String>();
/** /**
* <p>Maps property names to property IDs.</p> * <p>Maps property names to property IDs.</p>
*/ */
private Map dictionaryNameToID = new HashMap(); private Map<String,Long> dictionaryNameToID = new HashMap<String,Long>();
/** /**
* <p>Tells whether this object is pure or not.</p> * <p>Tells whether this object is pure or not.</p>
@ -71,25 +76,19 @@ public class CustomProperties extends HashMap
private boolean isPure = true; private boolean isPure = true;
/** /**
* <p>Puts a {@link CustomProperty} into this map. It is assumed that the * <p>Puts a {@link CustomProperty} into this map. It is assumed that the
* {@link CustomProperty} already has a valid ID. Otherwise use * {@link CustomProperty} already has a valid ID. Otherwise use
* {@link #put(CustomProperty)}.</p> * {@link #put(CustomProperty)}.</p>
*/ */
public Object put(final Object name, final Object customProperty) throws ClassCastException public CustomProperty put(final String name, final CustomProperty cp)
{ {
final CustomProperty cp = (CustomProperty) customProperty;
if (name == null) if (name == null)
{ {
/* Ignoring a property without a name. */ /* Ignoring a property without a name. */
isPure = false; isPure = false;
return null; return null;
} }
if (!(name instanceof String))
throw new ClassCastException("The name of a custom property must " +
"be a java.lang.String, but it is a " +
name.getClass().getName());
if (!(name.equals(cp.getName()))) if (!(name.equals(cp.getName())))
throw new IllegalArgumentException("Parameter \"name\" (" + name + throw new IllegalArgumentException("Parameter \"name\" (" + name +
") and custom property's name (" + cp.getName() + ") and custom property's name (" + cp.getName() +
@ -97,13 +96,13 @@ public class CustomProperties extends HashMap
/* Register name and ID in the dictionary. Mapping in both directions is possible. If there is already a */ /* Register name and ID in the dictionary. Mapping in both directions is possible. If there is already a */
final Long idKey = Long.valueOf(cp.getID()); final Long idKey = Long.valueOf(cp.getID());
final Object oldID = dictionaryNameToID.get(name); final Long oldID = dictionaryNameToID.get(name);
dictionaryIDToName.remove(oldID); dictionaryIDToName.remove(oldID);
dictionaryNameToID.put(name, idKey); dictionaryNameToID.put(name, idKey);
dictionaryIDToName.put(idKey, name); dictionaryIDToName.put(idKey, name);
/* Put the custom property into this map. */ /* Put the custom property into this map. */
final Object oldCp = super.remove(oldID); final CustomProperty oldCp = super.remove(oldID);
super.put(idKey, cp); super.put(idKey, cp);
return oldCp; return oldCp;
} }
@ -138,9 +137,9 @@ public class CustomProperties extends HashMap
else else
{ {
long max = 1; long max = 1;
for (final Iterator i = dictionaryIDToName.keySet().iterator(); i.hasNext();) for (final Iterator<Long> i = dictionaryIDToName.keySet().iterator(); i.hasNext();)
{ {
final long id = ((Long) i.next()).longValue(); final long id = i.next().longValue();
if (id > max) if (id > max)
max = id; max = id;
} }
@ -295,12 +294,28 @@ public class CustomProperties extends HashMap
/** /**
* Returns a set of all the names of our * Returns a set of all the names of our
* custom properties * custom properties. Equivalent to
* {@link #nameSet()}
*/ */
public Set keySet() { public Set keySet() {
return dictionaryNameToID.keySet(); return dictionaryNameToID.keySet();
} }
/**
* Returns a set of all the names of our
* custom properties
*/
public Set<String> nameSet() {
return dictionaryNameToID.keySet();
}
/**
* Returns a set of all the IDs of our
* custom properties
*/
public Set<String> idSet() {
return dictionaryNameToID.keySet();
}
/** /**
@ -325,14 +340,44 @@ public class CustomProperties extends HashMap
* *
* @return the dictionary. * @return the dictionary.
*/ */
Map getDictionary() Map<Long,String> getDictionary()
{ {
return dictionaryIDToName; return dictionaryIDToName;
} }
/** /**
* Checks against both String Name and Long ID
*/
public boolean containsKey(Object key) {
if(key instanceof Long) {
return super.containsKey((Long)key);
}
if(key instanceof String) {
return super.containsKey((Long)dictionaryNameToID.get(key));
}
return false;
}
/**
* Checks against both the property, and its values.
*/
public boolean containsValue(Object value) {
if(value instanceof CustomProperty) {
return super.containsValue((CustomProperty)value);
} else {
for(CustomProperty cp : super.values()) {
if(cp.getValue() == value) {
return true;
}
}
}
return false;
}
/**
* <p>Gets the codepage.</p> * <p>Gets the codepage.</p>
* *
* @return the codepage or -1 if the codepage is undefined. * @return the codepage or -1 if the codepage is undefined.
@ -340,9 +385,9 @@ public class CustomProperties extends HashMap
public int getCodepage() public int getCodepage()
{ {
int codepage = -1; int codepage = -1;
for (final Iterator i = this.values().iterator(); codepage == -1 && i.hasNext();) for (final Iterator<CustomProperty> i = this.values().iterator(); codepage == -1 && i.hasNext();)
{ {
final CustomProperty cp = (CustomProperty) i.next(); final CustomProperty cp = i.next();
if (cp.getID() == PropertyIDMap.PID_CODEPAGE) if (cp.getID() == PropertyIDMap.PID_CODEPAGE)
codepage = ((Integer) cp.getValue()).intValue(); codepage = ((Integer) cp.getValue()).intValue();
} }

View File

@ -577,7 +577,7 @@ public class DocumentSummaryInformation extends SpecialPropertySet
{ {
cps = new CustomProperties(); cps = new CustomProperties();
final Section section = (Section) getSections().get(1); final Section section = (Section) getSections().get(1);
final Map dictionary = section.getDictionary(); final Map<Long,String> dictionary = section.getDictionary();
final Property[] properties = section.getProperties(); final Property[] properties = section.getProperties();
int propertyCount = 0; int propertyCount = 0;
for (int i = 0; i < properties.length; i++) for (int i = 0; i < properties.length; i++)
@ -588,7 +588,7 @@ public class DocumentSummaryInformation extends SpecialPropertySet
{ {
propertyCount++; propertyCount++;
final CustomProperty cp = new CustomProperty(p, final CustomProperty cp = new CustomProperty(p,
(String) dictionary.get(Long.valueOf(id))); dictionary.get(Long.valueOf(id)));
cps.put(cp.getName(), cp); cps.put(cp.getName(), cp);
} }
} }
@ -607,7 +607,7 @@ public class DocumentSummaryInformation extends SpecialPropertySet
{ {
ensureSection2(); ensureSection2();
final MutableSection section = (MutableSection) getSections().get(1); final MutableSection section = (MutableSection) getSections().get(1);
final Map dictionary = customProperties.getDictionary(); final Map<Long,String> dictionary = customProperties.getDictionary();
section.clear(); section.clear();
/* Set the codepage. If both custom properties and section have a /* Set the codepage. If both custom properties and section have a
@ -621,9 +621,9 @@ public class DocumentSummaryInformation extends SpecialPropertySet
customProperties.setCodepage(cpCodepage); customProperties.setCodepage(cpCodepage);
section.setCodepage(cpCodepage); section.setCodepage(cpCodepage);
section.setDictionary(dictionary); section.setDictionary(dictionary);
for (final Iterator i = customProperties.values().iterator(); i.hasNext();) for (final Iterator<CustomProperty> i = customProperties.values().iterator(); i.hasNext();)
{ {
final Property p = (Property) i.next(); final Property p = i.next();
section.setProperty(p); section.setProperty(p);
} }
} }

View File

@ -53,7 +53,7 @@ public class MutableSection extends Section
* decision has been taken when specifying the "properties" field * decision has been taken when specifying the "properties" field
* as an Property[]. It should have been a {@link java.util.List}.</p> * as an Property[]. It should have been a {@link java.util.List}.</p>
*/ */
private List preprops; private List<Property> preprops;
@ -74,7 +74,7 @@ public class MutableSection extends Section
dirty = true; dirty = true;
formatID = null; formatID = null;
offset = -1; offset = -1;
preprops = new LinkedList(); preprops = new LinkedList<Property>();
} }
@ -145,7 +145,7 @@ public class MutableSection extends Section
public void setProperties(final Property[] properties) public void setProperties(final Property[] properties)
{ {
this.properties = properties; this.properties = properties;
preprops = new LinkedList(); preprops = new LinkedList<Property>();
for (int i = 0; i < properties.length; i++) for (int i = 0; i < properties.length; i++)
preprops.add(properties[i]); preprops.add(properties[i]);
dirty = true; dirty = true;
@ -276,8 +276,8 @@ public class MutableSection extends Section
*/ */
public void removeProperty(final long id) public void removeProperty(final long id)
{ {
for (final Iterator i = preprops.iterator(); i.hasNext();) for (final Iterator<Property> i = preprops.iterator(); i.hasNext();)
if (((Property) i.next()).getID() == id) if (i.next().getID() == id)
{ {
i.remove(); i.remove();
break; break;
@ -423,12 +423,10 @@ public class MutableSection extends Section
} }
/* Sort the property list by their property IDs: */ /* Sort the property list by their property IDs: */
Collections.sort(preprops, new Comparator() Collections.sort(preprops, new Comparator<Property>()
{ {
public int compare(final Object o1, final Object o2) public int compare(final Property p1, final Property p2)
{ {
final Property p1 = (Property) o1;
final Property p2 = (Property) o2;
if (p1.getID() < p2.getID()) if (p1.getID() < p2.getID())
return -1; return -1;
else if (p1.getID() == p2.getID()) else if (p1.getID() == p2.getID())
@ -440,7 +438,7 @@ public class MutableSection extends Section
/* Write the properties and the property list into their respective /* Write the properties and the property list into their respective
* streams: */ * streams: */
for (final ListIterator i = preprops.listIterator(); i.hasNext();) for (final ListIterator<Property> i = preprops.listIterator(); i.hasNext();)
{ {
final MutableProperty p = (MutableProperty) i.next(); final MutableProperty p = (MutableProperty) i.next();
final long id = p.getID(); final long id = p.getID();
@ -502,14 +500,14 @@ public class MutableSection extends Section
* @exception IOException if an I/O exception occurs. * @exception IOException if an I/O exception occurs.
*/ */
private static int writeDictionary(final OutputStream out, private static int writeDictionary(final OutputStream out,
final Map dictionary, final int codepage) final Map<Long,String> dictionary, final int codepage)
throws IOException throws IOException
{ {
int length = TypeWriter.writeUIntToStream(out, dictionary.size()); int length = TypeWriter.writeUIntToStream(out, dictionary.size());
for (final Iterator i = dictionary.keySet().iterator(); i.hasNext();) for (final Iterator<Long> i = dictionary.keySet().iterator(); i.hasNext();)
{ {
final Long key = (Long) i.next(); final Long key = i.next();
final String value = (String) dictionary.get(key); final String value = dictionary.get(key);
if (codepage == Constants.CP_UNICODE) if (codepage == Constants.CP_UNICODE)
{ {
@ -617,21 +615,11 @@ public class MutableSection extends Section
* *
* @see Section#getDictionary() * @see Section#getDictionary()
*/ */
public void setDictionary(final Map dictionary) public void setDictionary(final Map<Long,String> dictionary)
throws IllegalPropertySetDataException throws IllegalPropertySetDataException
{ {
if (dictionary != null) if (dictionary != null)
{ {
for (final Iterator i = dictionary.keySet().iterator();
i.hasNext();)
if (!(i.next() instanceof Long))
throw new IllegalPropertySetDataException
("Dictionary keys must be of type Long.");
for (final Iterator i = dictionary.values().iterator();
i.hasNext();)
if (!(i.next() instanceof String))
throw new IllegalPropertySetDataException
("Dictionary values must be of type String.");
this.dictionary = dictionary; this.dictionary = dictionary;
/* Set the dictionary property (ID 0). Please note that the second /* Set the dictionary property (ID 0). Please note that the second

View File

@ -42,7 +42,7 @@ public class Section
* <p>Maps property IDs to section-private PID strings. These * <p>Maps property IDs to section-private PID strings. These
* strings can be found in the property with ID 0.</p> * strings can be found in the property with ID 0.</p>
*/ */
protected Map dictionary; protected Map<Long,String> dictionary;
/** /**
* <p>The section's format ID, {@link #getFormatID}.</p> * <p>The section's format ID, {@link #getFormatID}.</p>
@ -244,10 +244,10 @@ public class Section
/* Look for the codepage. */ /* Look for the codepage. */
int codepage = -1; int codepage = -1;
for (final Iterator i = propertyList.iterator(); for (final Iterator<PropertyListEntry> i = propertyList.iterator();
codepage == -1 && i.hasNext();) codepage == -1 && i.hasNext();)
{ {
ple = (PropertyListEntry) i.next(); ple = i.next();
/* Read the codepage if the property ID is 1. */ /* Read the codepage if the property ID is 1. */
if (ple.id == PropertyIDMap.PID_CODEPAGE) if (ple.id == PropertyIDMap.PID_CODEPAGE)
@ -271,9 +271,9 @@ public class Section
/* Pass 2: Read all properties - including the codepage property, /* Pass 2: Read all properties - including the codepage property,
* if available. */ * if available. */
int i1 = 0; int i1 = 0;
for (final Iterator i = propertyList.iterator(); i.hasNext();) for (final Iterator<PropertyListEntry> i = propertyList.iterator(); i.hasNext();)
{ {
ple = (PropertyListEntry) i.next(); ple = i.next();
Property p = new Property(ple.id, src, Property p = new Property(ple.id, src,
this.offset + ple.offset, this.offset + ple.offset,
ple.length, codepage); ple.length, codepage);
@ -294,7 +294,7 @@ public class Section
* <p>Represents an entry in the property list and holds a property's ID and * <p>Represents an entry in the property list and holds a property's ID and
* its offset from the section's beginning.</p> * its offset from the section's beginning.</p>
*/ */
class PropertyListEntry implements Comparable class PropertyListEntry implements Comparable<PropertyListEntry>
{ {
int id; int id;
int offset; int offset;
@ -307,11 +307,9 @@ public class Section
* *
* @see Comparable#compareTo(java.lang.Object) * @see Comparable#compareTo(java.lang.Object)
*/ */
public int compareTo(final Object o) public int compareTo(final PropertyListEntry o)
{ {
if (!(o instanceof PropertyListEntry)) final int otherOffset = o.offset;
throw new ClassCastException(o.toString());
final int otherOffset = ((PropertyListEntry) o).offset;
if (offset < otherOffset) if (offset < otherOffset)
return -1; return -1;
else if (offset == otherOffset) else if (offset == otherOffset)
@ -630,7 +628,7 @@ public class Section
* @return the dictionary or <code>null</code> if the section does not have * @return the dictionary or <code>null</code> if the section does not have
* a dictionary. * a dictionary.
*/ */
public Map getDictionary() public Map<Long,String> getDictionary()
{ {
return dictionary; return dictionary;
} }

View File

@ -57,9 +57,9 @@ public class HPSFPropertiesExtractor extends POITextExtractor {
// Now custom ones // Now custom ones
CustomProperties cps = dsi == null ? null : dsi.getCustomProperties(); CustomProperties cps = dsi == null ? null : dsi.getCustomProperties();
if(cps != null) { if(cps != null) {
Iterator keys = cps.keySet().iterator(); Iterator<String> keys = cps.nameSet().iterator();
while(keys.hasNext()) { while(keys.hasNext()) {
String key = (String)keys.next(); String key = keys.next();
String val = getPropertyValueText( cps.get(key) ); String val = getPropertyValueText( cps.get(key) );
text.append(key + " = " + val + "\n"); text.append(key + " = " + val + "\n");
} }

View File

@ -348,8 +348,25 @@ public class TestWriteWellKnown extends TestCase {
customProperties.put("min_Long", MIN_LONG); customProperties.put("min_Long", MIN_LONG);
customProperties.put("max_Double", MAX_DOUBLE); customProperties.put("max_Double", MAX_DOUBLE);
customProperties.put("min_Double", MIN_DOUBLE); customProperties.put("min_Double", MIN_DOUBLE);
// Check the keys went in
assertTrue(customProperties.containsKey("Schl\u00fcssel \u00e4"));
assertTrue(customProperties.containsKey("Boolean"));
// Check the values went in
assertEquals("Wert \u00e4", customProperties.get("Schl\u00fcssel \u00e4"));
assertEquals(Boolean.TRUE, customProperties.get("Boolean"));
assertTrue(customProperties.containsValue(Boolean.TRUE));
assertTrue(customProperties.containsValue("Wert \u00e4"));
// Check that things that aren't in aren't in
assertFalse(customProperties.containsKey("False Boolean"));
assertFalse(customProperties.containsValue(Boolean.FALSE));
// Save as our custom properties
dsi.setCustomProperties(customProperties); dsi.setCustomProperties(customProperties);
/* Write the summary information stream and the document summary /* Write the summary information stream and the document summary
* information stream to the POI filesystem. */ * information stream to the POI filesystem. */
si.write(dir, siEntry.getName()); si.write(dir, siEntry.getName());